Compare commits

..
Author SHA1 Message Date
Sarooj Bukhari ee21c424a2 fix table jerks 2023-07-10 16:58:19 +05:00
Sarooj Bukhari 40cf40829c fix table jerks 2023-07-10 16:54:45 +05:00
Sarooj Bukhari 30cd602e41 update 2023-07-10 16:49:13 +05:00
Sarooj Bukhari a11511ecbf fix comments 2023-07-10 08:27:48 +05:00
Sarooj Bukhari 2ac5504bee fix comments 2023-07-10 08:26:18 +05:00
braginini f6476ecf05 All nameservers by default in the table 2023-07-09 11:31:48 +02:00
Sarooj Bukhari c8108ef01f fix delete issue 2023-07-07 20:11:06 +05:00
Sarooj Bukhari ad4e54129a fix delete issue 2023-07-07 20:07:00 +05:00
Sarooj Bukhari 57318de4c6 fix issue of CLA 2023-07-07 19:17:58 +05:00
Sarooj Bukhari 70c2f973ef fix issue of CLA 2023-07-07 19:15:25 +05:00
Sarooj Bukhari 3bbe1079af work on DNS layout 2023-07-07 19:14:54 +05:00
Sarooj Bukhari 923c00b70c work on DNS layout 2023-07-07 18:31:31 +05:00
38 changed files with 2697 additions and 4200 deletions

No files matched your search

+1 -6
View File
@@ -22,10 +22,6 @@ if [[ -z "${AUTH_AUDIENCE}" ]]; then
fi
fi
if [[ "${AUTH_AUDIENCE}" == "none" ]]; then
unset AUTH_AUDIENCE
fi
if [[ -z "${AUTH_SUPPORTED_SCOPES}" ]]; then
if [[ -z "${AUTH0_DOMAIN}" ]]; then
echo "AUTH_SUPPORTED_SCOPES environment variable must be set"
@@ -58,12 +54,11 @@ export NETBIRD_MGMT_API_ENDPOINT=$(echo $NETBIRD_MGMT_API_ENDPOINT | sed -E 's/(
export NETBIRD_MGMT_GRPC_API_ENDPOINT=${NETBIRD_MGMT_GRPC_API_ENDPOINT}
export NETBIRD_HOTJAR_TRACK_ID=${NETBIRD_HOTJAR_TRACK_ID}
export NETBIRD_TOKEN_SOURCE=${NETBIRD_TOKEN_SOURCE:-accessToken}
export NETBIRD_DRAG_QUERY_PARAMS=${NETBIRD_DRAG_QUERY_PARAMS:-false}
echo "NetBird latest version: ${NETBIRD_LATEST_VERSION}"
# replace ENVs in the config
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 \$\$NETBIRD_DRAG_QUERY_PARAMS"
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"
+84 -84
View File
@@ -204,9 +204,9 @@
}
},
"node_modules/@babel/core/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -237,9 +237,9 @@
}
},
"node_modules/@babel/eslint-parser/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -311,9 +311,9 @@
}
},
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -370,9 +370,9 @@
}
},
"node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -1706,9 +1706,9 @@
}
},
"node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -1918,9 +1918,9 @@
}
},
"node_modules/@babel/preset-env/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -5219,9 +5219,9 @@
}
},
"node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -7467,9 +7467,9 @@
}
},
"node_modules/eslint-plugin-jsx-a11y/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -7540,9 +7540,9 @@
}
},
"node_modules/eslint-plugin-react/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -9512,9 +9512,9 @@
}
},
"node_modules/istanbul-lib-instrument/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -10800,9 +10800,9 @@
}
},
"node_modules/make-dir/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"bin": {
"semver": "bin/semver.js"
}
@@ -14712,9 +14712,9 @@
}
},
"node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -15831,9 +15831,9 @@
}
},
"node_modules/tough-cookie": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
"integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
"dependencies": {
"psl": "^1.1.33",
"punycode": "^2.1.1",
@@ -16710,9 +16710,9 @@
}
},
"node_modules/word-wrap": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"engines": {
"node": ">=0.10.0"
}
@@ -17249,9 +17249,9 @@
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -17271,9 +17271,9 @@
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -17328,9 +17328,9 @@
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -17371,9 +17371,9 @@
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -18237,9 +18237,9 @@
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -18394,9 +18394,9 @@
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -20854,9 +20854,9 @@
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -22543,9 +22543,9 @@
}
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -22589,9 +22589,9 @@
}
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -23955,9 +23955,9 @@
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -24942,9 +24942,9 @@
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}
}
},
@@ -27566,9 +27566,9 @@
}
},
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"requires": {
"lru-cache": "^6.0.0"
}
@@ -28430,9 +28430,9 @@
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
},
"tough-cookie": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
"integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
"requires": {
"psl": "^1.1.33",
"punycode": "^2.1.1",
@@ -29069,9 +29069,9 @@
}
},
"word-wrap": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA=="
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
},
"workbox-background-sync": {
"version": "6.5.4",
+12 -1
View File
@@ -70,7 +70,16 @@ function App() {
return (
<>
<ConfigProvider
theme={{
token: {
borderRadius: 4,
colorPrimary: "#1890ff",
fontFamily: "Arial"
},
components: {Badge: {fontSizeSM: 20}},
}}
>
<Provider store={store}>
{!show && <SecureLoading padding="3em" width={50} height={50}/>}
{show &&
@@ -115,6 +124,8 @@ function App() {
</Layout>
}
</Provider>
</ConfigProvider>
</>
)
}
+29 -57
View File
@@ -50,7 +50,7 @@ interface FormPolicy {
}
const AccessControlEdit = () => {
const { optionRender, blueTagRender, tagGroups, grayTagRender } =
const { optionRender, blueTagRender, grayTagRender } =
useGetGroupTagHelpers();
const { getTokenSilently } = useGetTokenSilently();
@@ -81,7 +81,7 @@ const AccessControlEdit = () => {
biDirectional: false,
reverseDirectional: false,
});
// const [tagGroups, setTagGroups] = useState([] as string[]);
const [tagGroups, setTagGroups] = useState([] as string[]);
const [formPolicy, setFormPolicy] = useState({} as FormPolicy);
const [form] = Form.useForm();
const inputNameRef = useRef<any>(null);
@@ -99,9 +99,9 @@ const AccessControlEdit = () => {
useEffect(() => {
if (editDescription) inputDescriptionRef.current!.focus({ cursor: "end" });
}, [editDescription]);
// useEffect(() => {
// setTagGroups(groups?.map((g) => g.name) || []);
// }, [groups]);
useEffect(() => {
setTagGroups(groups?.map((g) => g.name) || []);
}, [groups]);
useEffect(() => {
if (!policy) return;
const fPolicy = {
@@ -115,10 +115,10 @@ const AccessControlEdit = () => {
ports: policy.rules[0].ports,
action: policy.rules[0].action,
tagSourceGroups: policy.rules[0].sources
? policy.rules[0].sources?.map((t) => t.id || "")
? policy.rules[0].sources?.map((t) => t.name)
: [],
tagDestinationGroups: policy.rules[0].destinations
? policy.rules[0].destinations?.map((t) => t.id || "")
? policy.rules[0].destinations?.map((t) => t.name)
: [],
} as FormPolicy;
setFormPolicy(fPolicy);
@@ -139,21 +139,17 @@ const AccessControlEdit = () => {
const createPolicyToSave = (): PolicyToSave => {
const sources =
groups
?.filter((g) => formPolicy.tagSourceGroups.includes(g.id || ""))
?.filter((g) => formPolicy.tagSourceGroups.includes(g.name))
.map((g) => g.id || "") || [];
const destinations =
groups
?.filter((g) => formPolicy.tagDestinationGroups.includes(g.id || ""))
?.filter((g) => formPolicy.tagDestinationGroups.includes(g.name))
.map((g) => g.id || "") || [];
const existingGroupsNames: any[] = groups?.map((g) => g.id);
const sourcesNoId = formPolicy.tagSourceGroups.filter(
(s) => !existingGroupsNames.includes(s)
(s) => !tagGroups.includes(s)
);
const destinationsNoId = formPolicy.tagDestinationGroups.filter(
(s) => !existingGroupsNames.includes(s)
(s) => !tagGroups.includes(s)
);
const groupsToSave = uniq([...sourcesNoId, ...destinationsNoId]);
return {
@@ -461,7 +457,11 @@ const AccessControlEdit = () => {
},
]}
/>
<Card bordered={true} style={{ marginBottom: "7px" }}>
<Card
bordered={true}
// title={setupKey.name}
style={{ marginBottom: "7px" }}
>
<div style={{ maxWidth: "550px" }}>
<Form
layout="vertical"
@@ -508,6 +508,7 @@ const AccessControlEdit = () => {
<Form.Item
name="name"
label=""
style={{ margin: "0" }}
rules={[
{
required: true,
@@ -531,7 +532,7 @@ const AccessControlEdit = () => {
{!editDescription ? (
<div
style={{
margin: "0 0 39px",
margin: "12px 0 30px",
lineHeight: "22px",
cursor: "pointer",
}}
@@ -550,7 +551,7 @@ const AccessControlEdit = () => {
<Form.Item
name="description"
label="Description"
style={{ marginTop: 10, fontWeight: "500" }}
style={{ marginTop: 24, fontWeight: "500" }}
>
<Input
placeholder="Add description..."
@@ -567,7 +568,7 @@ const AccessControlEdit = () => {
</Row>
</Header>
</Col>
<Col span={24} style={{ marginBottom: "15px" }}>
<Col span={24}>
<Form.Item name="enabled" label="">
<div
style={{
@@ -578,7 +579,6 @@ const AccessControlEdit = () => {
<Switch
onChange={handleChangeDisabled}
defaultChecked={policy.enabled}
size="small"
/>
<div>
<label
@@ -622,16 +622,9 @@ const AccessControlEdit = () => {
tagRender={blueTagRender}
onChange={handleChangeSource}
dropdownRender={dropDownRenderGroups}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option
key={index}
value={m.id}
serchValue={m.name}
>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
@@ -782,23 +775,16 @@ const AccessControlEdit = () => {
tagRender={blueTagRender}
onChange={handleChangeDestination}
dropdownRender={dropDownRenderGroups}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option
key={index}
value={m.id}
serchValue={m.name}
>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
</Col>
</Row>
</Col>
<Col span={24} style={{ marginBottom: "15px" }}>
<Col span={24}>
<Paragraph
type={"secondary"}
style={{ marginTop: "-15px", marginBottom: "30px" }}
@@ -807,7 +793,7 @@ const AccessControlEdit = () => {
protocol below
</Paragraph>
</Col>
<Col span={24} style={{ marginBottom: "15px" }}>
<Col span={24}>
<Row>
<Col span={10}>
<Form.Item
@@ -844,14 +830,7 @@ const AccessControlEdit = () => {
maxWidth: "260px",
fontWeight: "500",
}}
placeholder={
<div
color={"rgba(0,0,0,0.25)"}
className="arimo-font"
>
Select ports
</div>
}
placeholder={<div color={"rgba(0,0,0,0.25)"} className="arimo-font">Select ports</div>}
className="menlo-font"
value={formPolicyCopy}
disabled={true}
@@ -883,14 +862,7 @@ const AccessControlEdit = () => {
maxWidth: "260px",
fontWeight: "500",
}}
placeholder={
<div
color={"rgba(0,0,0,0.25)"}
className="arimo-font"
>
Select ports
</div>
}
placeholder={<div color={"rgba(0,0,0,0.25)"} className="arimo-font">Select ports</div>}
tagRender={grayTagRender}
onChange={handleChangePorts}
className="menlo-font"
@@ -918,7 +890,7 @@ const AccessControlEdit = () => {
justifyContent: "start",
padding: 0,
gap: "10px",
marginTop: "12px",
marginTop: "30px",
}}
key={0}
>
+22 -51
View File
@@ -50,12 +50,8 @@ interface FormPolicy {
}
const AccessControlNew = () => {
const {
optionRender,
blueTagRender,
tagGroups,
grayTagRender,
} = useGetGroupTagHelpers();
const { optionRender, grayTagRender, blueTagRender } =
useGetGroupTagHelpers();
const { getTokenSilently } = useGetTokenSilently();
const dispatch = useDispatch();
const setupNewPolicyVisible = useSelector(
@@ -85,7 +81,7 @@ const AccessControlNew = () => {
biDirectional: true,
reverseDirectional: true,
});
// const [tagGroups, setTagGroups] = useState([] as string[]);
const [tagGroups, setTagGroups] = useState([] as string[]);
const [formPolicy, setFormPolicy] = useState({} as FormPolicy);
const [form] = Form.useForm();
const inputNameRef = useRef<any>(null);
@@ -97,9 +93,9 @@ const AccessControlNew = () => {
useEffect(() => {
if (editDescription) inputDescriptionRef.current!.focus({ cursor: "end" });
}, [editDescription]);
// useEffect(() => {
// setTagGroups(groups?.map((g) => g.name) || []);
// }, [groups]);
useEffect(() => {
setTagGroups(groups?.map((g) => g.name) || []);
}, [groups]);
useEffect(() => {
if (!policy) return;
const fPolicy = {
@@ -126,26 +122,19 @@ const AccessControlNew = () => {
const createPolicyToSave = (): PolicyToSave => {
const sources =
groups
?.filter((g) => formPolicy.tagSourceGroups.includes(g.id || ""))
?.filter((g) => formPolicy.tagSourceGroups.includes(g.name))
.map((g) => g.id || "") || [];
const destinations =
groups
?.filter((g) => formPolicy.tagDestinationGroups.includes(g.id || ""))
?.filter((g) => formPolicy.tagDestinationGroups.includes(g.name))
.map((g) => g.id || "") || [];
const existingGroupsNames: any[] = groups?.map((g) => g.id);
const sourcesNoId = formPolicy.tagSourceGroups.filter(
(s) => !existingGroupsNames.includes(s)
(s) => !tagGroups.includes(s)
);
const destinationsNoId = formPolicy.tagDestinationGroups.filter(
(s) => !existingGroupsNames.includes(s)
(s) => !tagGroups.includes(s)
);
const groupsToSave = uniq([...sourcesNoId, ...destinationsNoId]);
return {
id: formPolicy.id,
name: formPolicy.name,
@@ -467,20 +456,18 @@ const AccessControlNew = () => {
textAlign: "start",
whiteSpace: "pre-line",
fontSize: "18px",
margin: "0px",
fontWeight: "500",
}}
>
Create rule
Create Rule
</Paragraph>
<Paragraph
type={"secondary"}
style={{
textAlign: "start",
whiteSpace: "pre-line",
marginTop: "-20px",
fontSize: "14px",
paddingBottom: "25px",
marginBottom: "4px",
paddingBottom: "15px",
}}
>
Use this rule to restrict access to groups of resources
@@ -573,12 +560,9 @@ const AccessControlNew = () => {
tagRender={blueTagRender}
onChange={handleChangeSource}
dropdownRender={dropDownRenderGroups}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option key={index} value={m.id} serchValue={m.name}>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
@@ -729,12 +713,9 @@ const AccessControlNew = () => {
tagRender={blueTagRender}
onChange={handleChangeDestination}
dropdownRender={dropDownRenderGroups}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option key={index} value={m.id} serchValue={m.name}>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
@@ -786,8 +767,6 @@ const AccessControlNew = () => {
color: "rgba(0, 0, 0, 0.88)",
fontSize: "14px",
fontWeight: "500",
padding: "0 0 2px",
display: "inline-block",
}}
>
Ports
@@ -849,16 +828,9 @@ const AccessControlNew = () => {
className="menlo-font"
placeholder={
formPolicy.protocol === "all" ||
formPolicy.protocol === "icmp" ? (
"All"
) : (
<div
color={"rgba(0,0,0,0.25)"}
className="arimo-font"
>
Select ports
</div>
)
formPolicy.protocol === "icmp"
? "All"
: (<div color={"rgba(0,0,0,0.25)"} className="arimo-font">Select ports</div>)
}
tagRender={grayTagRender}
onChange={handleChangePorts}
@@ -887,7 +859,6 @@ const AccessControlNew = () => {
}}
>
<Switch
size="small"
onChange={handleChangeDisabled}
defaultChecked={true}
/>
@@ -919,7 +890,7 @@ const AccessControlNew = () => {
</Col>
<Col
span={24}
style={{ marginTop: "10px", marginBottom: "24px" }}
style={{ marginTop: "20px", marginBottom: "25px" }}
>
<Text type={"secondary"}>
Learn more about
@@ -929,7 +900,7 @@ const AccessControlNew = () => {
href="https://docs.netbird.io/how-to/manage-network-access"
>
{" "}
access controls
Access Controls
</a>
</Text>
</Col>
+138 -126
View File
@@ -32,7 +32,6 @@ import {
} from "../store/nameservers/types";
import { useGetGroupTagHelpers } from "../utils/groups";
import { useGetTokenSilently } from "../utils/token";
import { domainValidator } from "../utils/common";
const { Paragraph, Text } = Typography;
@@ -273,6 +272,21 @@ const NameServerGroupAdd = () => {
setEditDescription(status);
};
const domainRegex =
/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/;
const domainValidator = (_: RuleObject, domain: string) => {
if (domainRegex.test(domain)) {
return Promise.resolve();
}
setIsPrimary(false);
return Promise.reject(
new Error(
"Please enter a valid domain, e.g. example.com or intra.example.com"
)
);
};
const nameValidator = (_: RuleObject, value: string) => {
const found = nsGroupData.find(
(u) => u.name == value && u.id !== formNSGroup.id
@@ -317,117 +331,121 @@ const NameServerGroupAdd = () => {
{ add, remove }: any,
{ errors }: any
) => (
<div style={{ width: "100%", maxWidth: "360px" }}>
<label
style={{
color: "rgba(0, 0, 0, 0.88)",
fontSize: "14px",
fontWeight: "500",
marginBottom: "10px",
display: "block",
}}
>
Nameservers
</label>
<Col>
<div style={{ width: "100%", maxWidth: "360px" }}>
<label
style={{
color: "rgba(0, 0, 0, 0.88)",
fontSize: "14px",
fontWeight: "500",
marginBottom: "10px",
display: "block",
}}
>
Nameservers
</label>
{!!fields.length && (
<Row align="middle">
<Col span={4} style={{ textAlign: "left" }}>
<Typography.Text
style={{ color: "#818183", paddingLeft: "5px" }}
></Typography.Text>
</Col>
<Col span={10} style={{ textAlign: "left" }}>
<Typography.Text style={{ color: "#818183", paddingLeft: "5px" }}>
Nameserver IP
</Typography.Text>
</Col>
<Col span={4} style={{ textAlign: "left" }}>
<Typography.Text style={{ color: "#818183", paddingLeft: "5px" }}>
Port
</Typography.Text>
</Col>
<Col span={4} />
</Row>
)}
{fields.map((field, index) => {
return (
<Row key={index}>
{!!fields.length && (
<Row align="middle">
<Col span={4} style={{ textAlign: "left" }}>
<Form.Item
style={{ margin: "3px" }}
name={[field.name, "ns_type"]}
rules={[{ required: true, message: "Missing first protocol" }]}
initialValue={"udp"}
>
<Select
disabled
style={{ width: "100%" }}
className="style-like-text"
>
<Option value="udp">UDP</Option>
</Select>
</Form.Item>
<Typography.Text
style={{ color: "#818183", paddingLeft: "5px" }}
></Typography.Text>
</Col>
<Col span={10} style={{ margin: "1px" }}>
<Form.Item
style={{ margin: "1px" }}
name={[field.name, "ip"]}
rules={[{ validator: ipValidator }]}
>
<Input
placeholder="e.g. X.X.X.X"
style={{ width: "100%" }}
autoComplete="off"
/>
</Form.Item>
<Col span={10} style={{ textAlign: "left" }}>
<Typography.Text style={{ color: "#818183", paddingLeft: "5px" }}>
Nameserver IP
</Typography.Text>
</Col>
<Col span={4} style={{ textAlign: "center" }}>
<Form.Item
style={{ margin: "1px" }}
name={[field.name, "port"]}
rules={[{ required: true, message: "Missing port" }]}
initialValue={53}
>
<InputNumber placeholder="Port" style={{ width: "100%" }} />
</Form.Item>
</Col>
<Col
span={2}
style={{
textAlign: "center",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<MinusCircleOutlined onClick={() => remove(field.name)} />
<Col span={4} style={{ textAlign: "left" }}>
<Typography.Text style={{ color: "#818183", paddingLeft: "5px" }}>
Port
</Typography.Text>
</Col>
<Col span={4} />
</Row>
);
})}
)}
{fields.map((field, index) => {
return (
<Row key={index}>
<Col span={4} style={{ textAlign: "left" }}>
<Form.Item
style={{ margin: "3px" }}
name={[field.name, "ns_type"]}
rules={[
{ required: true, message: "Missing first protocol" },
]}
initialValue={"udp"}
>
<Select
disabled
style={{ width: "100%" }}
className="style-like-text"
>
<Option value="udp">UDP</Option>
</Select>
</Form.Item>
</Col>
<Col span={10} style={{ margin: "1px" }}>
<Form.Item
style={{ margin: "1px" }}
name={[field.name, "ip"]}
rules={[{ validator: ipValidator }]}
>
<Input
placeholder="e.g. X.X.X.X"
style={{ width: "100%" }}
autoComplete="off"
/>
</Form.Item>
</Col>
<Col span={4} style={{ textAlign: "center" }}>
<Form.Item
style={{ margin: "1px" }}
name={[field.name, "port"]}
rules={[{ required: true, message: "Missing port" }]}
initialValue={53}
>
<InputNumber placeholder="Port" style={{ width: "100%" }} />
</Form.Item>
</Col>
<Col
span={2}
style={{
textAlign: "center",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Col>
</Row>
);
})}
<Row>
<Col span={20}>
<Form.Item>
<Button
type="dashed"
onClick={() => add()}
block
style={{
maxWidth: "270px",
marginTop: "5px",
}}
disabled={fields.length > 1}
icon={<PlusOutlined />}
>
Add nameserver
</Button>
<Form.ErrorList errors={errors} />
</Form.Item>
</Col>
</Row>
</div>
<Row>
<Col span={20}>
<Form.Item>
<Button
type="dashed"
onClick={() => add()}
block
style={{
maxWidth: "270px",
marginTop: "5px",
}}
disabled={fields.length > 1}
icon={<PlusOutlined />}
>
Add Nameserver
</Button>
<Form.ErrorList errors={errors} />
</Form.Item>
</Col>
</Row>
</div>
</Col>
);
// @ts-ignore
@@ -452,9 +470,9 @@ const NameServerGroupAdd = () => {
<Paragraph
type={"secondary"}
style={{
marginTop: "-4px",
marginTop: "-2",
fontWeight: "400",
marginBottom: "4px",
marginBottom: "0",
}}
>
Add domain if you want to have a specific one
@@ -538,20 +556,18 @@ const NameServerGroupAdd = () => {
textAlign: "start",
whiteSpace: "pre-line",
fontSize: "18px",
margin: "0px",
fontWeight: "500",
}}
>
Add nameserver
Add Nameserver
</Paragraph>
<Paragraph
type={"secondary"}
style={{
textAlign: "start",
whiteSpace: "pre-line",
marginTop: "-20px",
fontSize: "14px",
paddingBottom: "25px",
marginBottom: "4px",
paddingBottom: "0",
}}
>
Use this nameserver to resolve domains in your network
@@ -690,7 +706,7 @@ const NameServerGroupAdd = () => {
</Row>
</Header>
</Col>
<Col span={24}>
<Col span={24} flex="auto">
<Form.List
name="nameservers"
rules={[{ validator: formListValidator }]}
@@ -698,7 +714,7 @@ const NameServerGroupAdd = () => {
{renderNSList}
</Form.List>
</Col>
<Col span={24}>
<Col span={24} flex="auto">
<Form.List name="domains">{renderDomains}</Form.List>
</Col>
<Col span={24}>
@@ -714,9 +730,9 @@ const NameServerGroupAdd = () => {
<Paragraph
type={"secondary"}
style={{
marginTop: "-4px",
marginTop: "-2",
fontWeight: "400",
marginBottom: "4px",
marginBottom: "0",
}}
>
Advertise this route to peers that belong to the following
@@ -733,12 +749,9 @@ const NameServerGroupAdd = () => {
tagRender={blueTagRender}
onChange={handleChangeTags}
dropdownRender={dropDownRender}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option key={index} value={m.id} serchValue={m.name}>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
@@ -774,9 +787,8 @@ const NameServerGroupAdd = () => {
marginBottom: "0",
}}
>
{formNSGroup.enabled
? "Disable this server if you don't want it to apply immediately"
: " Enable this server if you want it to apply immediately"}
Disable this server if you don't want it to apply
immediately
</Paragraph>
</div>
</div>
@@ -784,7 +796,7 @@ const NameServerGroupAdd = () => {
</Col>
<Col
span={24}
style={{ marginTop: "10px", marginBottom: "24px" }}
style={{ marginTop: "10px", marginBottom: "20px" }}
>
<Text type={"secondary"}>
Learn more about
@@ -818,7 +830,7 @@ const NameServerGroupAdd = () => {
onClick={handleFormSubmit}
disabled={savedNSGroup.loading}
>
Create nameserver
Create Nameserver
</Button>
</Space>
</Col>
+184 -169
View File
@@ -30,7 +30,7 @@ import {
import { useGetGroupTagHelpers } from "../utils/groups";
import { useGetTokenSilently } from "../utils/token";
import { Container } from "./Container";
import { domainValidator } from "../utils/common";
const { Paragraph, Text } = Typography;
interface formNSGroup extends NameServerGroup {}
@@ -43,6 +43,7 @@ const NameServerGroupUpdate = () => {
optionRender,
tagGroups,
getExistingAndToCreateGroupsLists,
getGroupNamesFromIDs,
selectValidator,
} = useGetGroupTagHelpers();
const dispatch = useDispatch();
@@ -95,7 +96,7 @@ const NameServerGroupUpdate = () => {
let newFormGroup = {
...nsGroup,
groups: nsGroup.groups,
groups: getGroupNamesFromIDs(nsGroup.groups),
} as formNSGroup;
setFormNSGroup(newFormGroup);
form.setFieldsValue(newFormGroup);
@@ -253,6 +254,21 @@ const NameServerGroupUpdate = () => {
setEditDescription(status);
};
const domainRegex =
/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/;
const domainValidator = (_: RuleObject, domain: string) => {
if (domainRegex.test(domain)) {
return Promise.resolve();
}
setIsPrimary(false);
return Promise.reject(
new Error(
"Please enter a valid domain, e.g. example.com or intra.example.com"
)
);
};
const nameValidator = (_: RuleObject, value: string) => {
const found = nsGroupData.find(
(u) => u.name == value && u.id !== formNSGroup.id
@@ -297,161 +313,117 @@ const NameServerGroupUpdate = () => {
{ add, remove }: any,
{ errors }: any
) => (
<Row>
<Col span={24} style={{ marginBottom: "15px" }}>
<Form.Item name="enabled" label="">
<div
style={{
display: "flex",
gap: "15px",
}}
>
<Switch
onChange={handleChangeDisabled}
defaultChecked={formNSGroup.enabled}
size="small"
checked={formNSGroup.enabled}
/>
<div>
<label
style={{
color: "rgba(0, 0, 0, 0.88)",
fontSize: "14px",
fontWeight: "500",
}}
>
Enabled
</label>
<Paragraph
type={"secondary"}
style={{
marginTop: "-2",
fontWeight: "400",
marginBottom: "0",
}}
>
{formNSGroup.enabled
? "Disable this server if you don't want the configuration to apply immediately"
: " Enable this server if you want the configuration to apply immediately"}
</Paragraph>
</div>
</div>
</Form.Item>
</Col>
<Col>
<div style={{ width: "100%", maxWidth: "360px" }}>
<label
style={{
color: "rgba(0, 0, 0, 0.88)",
fontSize: "14px",
fontWeight: "500",
marginBottom: "10px",
display: "block",
}}
>
Nameservers
</label>
<Col>
<div style={{ width: "100%", maxWidth: "360px" }}>
<label
style={{
color: "rgba(0, 0, 0, 0.88)",
fontSize: "14px",
fontWeight: "500",
marginBottom: "10px",
display: "block",
}}
>
Nameservers
</label>
{!!fields.length && (
<Row align="middle">
<Col span={4} style={{ textAlign: "left" }}>
<Text style={{ color: "#818183", paddingLeft: "5px" }}></Text>
</Col>
<Col span={10} style={{ textAlign: "left" }}>
<Text style={{ color: "#818183", paddingLeft: "5px" }}>
Nameserver IP
</Text>
</Col>
<Col span={4} style={{ textAlign: "left" }}>
<Text style={{ color: "#818183", paddingLeft: "5px" }}>
Port
</Text>
</Col>
<Col span={4} />
</Row>
)}
{fields.map((field, index) => {
return (
<Row key={index}>
<Col span={4} style={{ textAlign: "left" }}>
<Form.Item
style={{ margin: "3px" }}
name={[field.name, "ns_type"]}
rules={[
{ required: true, message: "Missing first protocol" },
]}
initialValue={"udp"}
>
<Select
disabled
style={{ width: "100%" }}
className="style-like-text"
>
<Option value="udp">UDP</Option>
</Select>
</Form.Item>
</Col>
<Col span={10} style={{ margin: "1px" }}>
<Form.Item
style={{ margin: "1px" }}
name={[field.name, "ip"]}
rules={[{ validator: ipValidator }]}
>
<Input
placeholder="e.g. X.X.X.X"
style={{ width: "100%" }}
autoComplete="off"
/>
</Form.Item>
</Col>
<Col span={4} style={{ textAlign: "center" }}>
<Form.Item
style={{ margin: "1px" }}
name={[field.name, "port"]}
rules={[{ required: true, message: "Missing port" }]}
initialValue={53}
>
<InputNumber placeholder="Port" style={{ width: "100%" }} />
</Form.Item>
</Col>
<Col
span={2}
style={{
textAlign: "center",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Col>
</Row>
);
})}
<Row>
<Col span={20}>
<Form.Item>
<Button
type="dashed"
onClick={() => add()}
block
style={{
maxWidth: "270px",
marginTop: "5px",
}}
disabled={fields.length > 1}
icon={<PlusOutlined />}
>
Add Nameserver
</Button>
<Form.ErrorList errors={errors} />
</Form.Item>
{!!fields.length && (
<Row align="middle">
<Col span={4} style={{ textAlign: "left" }}>
<Text style={{ color: "#818183", paddingLeft: "5px" }}></Text>
</Col>
<Col span={10} style={{ textAlign: "left" }}>
<Text style={{ color: "#818183", paddingLeft: "5px" }}>
Nameserver IP
</Text>
</Col>
<Col span={4} style={{ textAlign: "left" }}>
<Text style={{ color: "#818183", paddingLeft: "5px" }}>Port</Text>
</Col>
<Col span={4} />
</Row>
</div>
</Col>
</Row>
)}
{fields.map((field, index) => {
return (
<Row key={index}>
<Col span={4} style={{ textAlign: "left" }}>
<Form.Item
style={{ margin: "3px" }}
name={[field.name, "ns_type"]}
rules={[
{ required: true, message: "Missing first protocol" },
]}
initialValue={"udp"}
>
<Select
disabled
style={{ width: "100%" }}
className="style-like-text"
>
<Option value="udp">UDP</Option>
</Select>
</Form.Item>
</Col>
<Col span={10} style={{ margin: "1px" }}>
<Form.Item
style={{ margin: "1px" }}
name={[field.name, "ip"]}
rules={[{ validator: ipValidator }]}
>
<Input
placeholder="e.g. X.X.X.X"
style={{ width: "100%" }}
autoComplete="off"
/>
</Form.Item>
</Col>
<Col span={4} style={{ textAlign: "center" }}>
<Form.Item
style={{ margin: "1px" }}
name={[field.name, "port"]}
rules={[{ required: true, message: "Missing port" }]}
initialValue={53}
>
<InputNumber placeholder="Port" style={{ width: "100%" }} />
</Form.Item>
</Col>
<Col
span={2}
style={{
textAlign: "center",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Col>
</Row>
);
})}
<Row>
<Col span={20}>
<Form.Item>
<Button
type="dashed"
onClick={() => add()}
block
style={{
maxWidth: "270px",
marginTop: "5px",
}}
disabled={fields.length > 1}
icon={<PlusOutlined />}
>
Add Nameserver
</Button>
<Form.ErrorList errors={errors} />
</Form.Item>
</Col>
</Row>
</div>
</Col>
);
// @ts-ignore
@@ -476,13 +448,24 @@ const NameServerGroupUpdate = () => {
<Paragraph
type={"secondary"}
style={{
marginTop: "-2",
fontWeight: "400",
marginBottom: "10px",
marginBottom: "0",
}}
>
Add domain if you want to have a specific one
</Paragraph>
</Col>
{/* <Col>
<Tooltip
title="Only queries to domains specified here will be resolved by these nameservers."
className={"ant-form-item-tooltip"}
>
<QuestionCircleOutlined
style={{ color: "rgba(0, 0, 0, 0.45)", cursor: "help" }}
/>
</Tooltip>
</Col> */}
</Space>
</Row>
{fields.map((field, index) => {
@@ -648,7 +631,7 @@ const NameServerGroupUpdate = () => {
className={
"access-control input-text ant-drawer-subtitle"
}
style={{ margin: "0 0 39px 0px" }}
style={{ marginTop: "0" }}
onClick={() => toggleEditDescription(true)}
>
{formNSGroup.description &&
@@ -658,7 +641,7 @@ const NameServerGroupUpdate = () => {
</div>
) : (
<Row>
<Col span={8} style={{ marginBottom: "15px" }}>
<Col span={8}>
<div
style={{ lineHeight: "15px", marginTop: "24px" }}
>
@@ -693,8 +676,46 @@ const NameServerGroupUpdate = () => {
</Row>
</Header>
</Col>
<Col span={24} style={{ marginBottom: "15px" }}>
<Col span={24}>
<Form.Item name="enabled" label="">
<div
style={{
display: "flex",
gap: "15px",
}}
>
<Switch
onChange={handleChangeDisabled}
defaultChecked={formNSGroup.enabled}
size="small"
checked={formNSGroup.enabled}
/>
<div>
<label
style={{
color: "rgba(0, 0, 0, 0.88)",
fontSize: "14px",
fontWeight: "500",
}}
>
Enabled
</label>
<Paragraph
type={"secondary"}
style={{
marginTop: "-2",
fontWeight: "400",
marginBottom: "0",
}}
>
Disable this server if you don't want it to apply
immediately
</Paragraph>
</div>
</div>
</Form.Item>
</Col>
<Col span={24}>
<Form.List
name="nameservers"
rules={[{ validator: formListValidator }]}
@@ -703,17 +724,15 @@ const NameServerGroupUpdate = () => {
</Form.List>
</Col>
<Col span={24} style={{ marginBottom: "15px" }}>
<Col span={24}>
<Form.List name="domains">{renderDomains}</Form.List>
</Col>
<Col span={24} style={{ marginBottom: "15px" }}>
<Col span={24}>
<label
style={{
color: "rgba(0, 0, 0, 0.88)",
fontSize: "14px",
fontWeight: "500",
marginBottom: "5px",
display: "block",
}}
>
Distribution groups
@@ -730,17 +749,13 @@ const NameServerGroupUpdate = () => {
tagRender={blueTagRender}
onChange={handleChangeTags}
dropdownRender={dropDownRender}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option key={index} value={m.id} serchValue={m.name}>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
</Col>
<Col
style={{
width: "100%",
+169 -227
View File
@@ -1,243 +1,185 @@
import React, { useEffect, useState } from "react";
import { Link, useLocation } from "react-router-dom";
import React, {useEffect, useState} from 'react';
import {Link, useLocation} from 'react-router-dom';
import logo from "../assets/logo.png";
import { Avatar, Button, Col, Dropdown, Grid, Menu, Row } from "antd";
import { ItemType } from "antd/lib/menu/hooks/useItems";
import { AvatarSize } from "antd/es/avatar/SizeContext";
import { UserOutlined } from "@ant-design/icons";
import { useOidc, useOidcIdToken, useOidcUser } from "@axa-fr/react-oidc";
import { getConfig } from "../config";
import { User } from "../store/user/types";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "typesafe-actions";
import { actions as userActions } from "../store/user";
import { useGetTokenSilently } from "../utils/token";
import { actions as personalAccessTokenActions } from "../store/personal-access-token";
import {Avatar, Button, Col, Dropdown, Grid, Menu, Row} from 'antd'
import {ItemType} from "antd/lib/menu/hooks/useItems";
import {AvatarSize} from "antd/es/avatar/SizeContext";
import {UserOutlined} from '@ant-design/icons';
import {useOidc, useOidcIdToken, useOidcUser} from '@axa-fr/react-oidc';
import {getConfig} from "../config";
import {User} from "../store/user/types";
import {useDispatch, useSelector} from "react-redux";
import {RootState} from "typesafe-actions";
import {actions as userActions} from "../store/user";
import {useGetTokenSilently} from "../utils/token";
import {actions as personalAccessTokenActions} from "../store/personal-access-token";
const { useBreakpoint } = Grid;
const {useBreakpoint} = Grid;
const Navbar = () => {
let location = useLocation();
const config = getConfig();
const { logout } = useOidc();
const { getTokenSilently } = useGetTokenSilently();
const dispatch = useDispatch();
let location = useLocation();
const config = getConfig();
const { logout } = useOidc();
const {getTokenSilently} = useGetTokenSilently()
const dispatch = useDispatch()
const { oidcUser } = useOidcUser();
const { idTokenPayload } = useOidcIdToken();
const user = oidcUser;
const [currentUser, setCurrentUser] = useState({} as User);
const {oidcUser} = useOidcUser();
const {idTokenPayload} = useOidcIdToken()
const user = oidcUser;
const [currentUser, setCurrentUser] = useState({} as User)
const screens = useBreakpoint();
const screens = useBreakpoint();
const [hideMenuUser, setHideMenuUser] = useState(false);
const users = useSelector((state: RootState) => state.user.data);
const [isRefreshingUserState, setIsRefreshingUserState] = useState(false);
const [hideMenuUser, setHideMenuUser] = useState(false)
const users = useSelector((state: RootState) => state.user.data)
const [isRefreshingUserState, setIsRefreshingUserState] = useState(false)
const items = [
{ label: <Link to="/peers">Peers</Link>, key: "/peers" },
{ label: <Link to="/setup-keys">Setup Keys</Link>, key: "/setup-keys" },
{ label: <Link to="/acls">Access Control</Link>, key: "/acls" },
{ label: <Link to="/routes">Network Routes</Link>, key: "/routes" },
{ label: <Link to="/dns">DNS</Link>, key: "/dns" },
{ label: <Link to="/users">Users</Link>, key: "/users" },
{ label: <Link to="/activity">Activity</Link>, key: "/activity" },
{ label: <Link to="/settings">Settings</Link>, key: "/settings" },
] as ItemType[];
const items = [
{label: (<Link to="/peers">Peers</Link>), key: '/peers'},
{label: (<Link to="/setup-keys">Setup Keys</Link>), key: '/setup-keys'},
{label: (<Link to="/acls">Access Control</Link>), key: '/acls'},
{label: (<Link to="/routes">Network Routes</Link>), key: '/routes'},
{ label: (<Link to="/dns">DNS</Link>), key: '/dns' },
{label: (<Link to="/users">Users</Link>), key: '/users'},
{label: (<Link to="/activity">Activity</Link>), key: '/activity'},
{label: (<Link to="/settings">Settings</Link>), key: '/settings'}
] as ItemType[]
const userEmailKey = "user-email";
const userLogoutKey = "user-logout";
const userDividerKey = "user-divider";
const adminOnlyTabs = [
"/setup-keys",
"/acls",
"/routes",
"/dns",
"/activity",
"/settings",
];
const [menuItems, setMenuItems] = useState(items);
const logoutWithRedirect = () => {
let lRemove = [
"peerFilter",
"setupKeysFilter",
"accessControlFilter",
"routesFilter",
"nameServerFilter",
"userFilter",
"serviceUserFilter",
"activityFilter",
];
lRemove.forEach((element) => {
localStorage.removeItem(element);
});
logout("/", { client_id: config.clientId });
};
const userEmailKey = 'user-email'
const userLogoutKey = 'user-logout'
const userDividerKey = 'user-divider'
const adminOnlyTabs = ["/setup-keys", "/acls", "/routes", "/dns", "/activity", "/settings"]
const [menuItems, setMenuItems] = useState(items)
const logoutWithRedirect = () =>
logout("/", {client_id: config.clientId});
const openPersonalUserPage = () => {
dispatch(
userActions.setUser({
id: currentUser.id,
email: currentUser.email,
role: currentUser.role,
auto_groups: currentUser.auto_groups ? currentUser.auto_groups : [],
name: currentUser.name,
is_current: currentUser.is_current,
is_service_user: currentUser.is_service_user,
} as User)
const openPersonalUserPage = () => {
dispatch(userActions.setUser({
id: currentUser.id,
email: currentUser.email,
role: currentUser.role,
auto_groups: currentUser.auto_groups ? currentUser.auto_groups : [],
name: currentUser.name,
is_current: currentUser.is_current,
is_service_user: currentUser.is_service_user,
} as User));
dispatch(userActions.setUserTabOpen("Users"));
dispatch(userActions.setEditUserPopupVisible(true));
}
useEffect(() => {
const fs = items.filter(m => showTab(m?.key?.toString(), currentUser) && m?.key !== userEmailKey && m?.key !== userLogoutKey && m?.key !== userDividerKey)
if (screens.xs === true) {
setHideMenuUser(false)
fs.push({type: 'divider', key: userDividerKey})
fs.push({
label: (
<Link to="#">{user?.name}</Link>
),
icon: createAvatar("small"),
key: userEmailKey
})
fs.push({
label: (<Button type="link" block onClick={logoutWithRedirect}>Logout</Button>),
key: userLogoutKey
})
setMenuItems([...fs])
return
}
setMenuItems([...fs])
setHideMenuUser(true)
}, [screens, currentUser])
useEffect(() => {
if (users.length === 0 && !isRefreshingUserState &&
window.location.pathname !== '/peers' &&
window.location.pathname !== '/users') {
setIsRefreshingUserState(true)
dispatch(userActions.getUsers.request({getAccessTokenSilently: getTokenSilently, payload: null}))
return
}
if (users.length === 0 && isRefreshingUserState) {
return
}
let runUser = oidcUser
if (!oidcUser) {
runUser = idTokenPayload
}
setIsRefreshingUserState(false)
if (runUser) {
const found = users.find(u => u.is_current ? u.is_current : runUser.sub ? u.id == runUser.sub : false)
if (found) {
setCurrentUser(found)
}
}
}, [users, oidcUser])
const showTab = (key: string | undefined, user: User | undefined) => {
if (!user) {
return false
}
if (user.role?.toLowerCase() === "admin") {
return true
}
return !adminOnlyTabs.find(t => t === key)
}
const menuUser = (
<Menu
items={[
{
label: (<Link to="/users" onClick={openPersonalUserPage}>{user?.email}</Link>),
key: '0',
},
{
label: (<Link to="/logout" onClick={logoutWithRedirect}>Logout</Link>),
key: '1',
}
]}
/>
);
dispatch(userActions.setUserTabOpen("Users"));
dispatch(userActions.setEditUserPopupVisible(true));
};
useEffect(() => {
const fs = items.filter(
(m) =>
showTab(m?.key?.toString(), currentUser) &&
m?.key !== userEmailKey &&
m?.key !== userLogoutKey &&
m?.key !== userDividerKey
const createAvatar = (size: AvatarSize) => {
return user?.picture ? (
<Avatar size={size} src={user?.picture} icon={<UserOutlined/>}/>
) : (
<Avatar size={size}>{(user?.name || '').slice(0, 1).toUpperCase()}</Avatar>
)
}
return (
<>
<Row justify="space-evenly" align="middle">
<Col flex="0 1 60px">
<Link id="logo" to="/">
<img
alt="logo"
style={{width: "55px"}}
src={logo}
/>
</Link>
</Col>
<Col flex="1 1 auto">
<div>
<Menu mode="horizontal" selectable={true} selectedKeys={[location.pathname]}
onSelect={(e) => {
dispatch(userActions.setUser(null as unknown as User));
dispatch(personalAccessTokenActions.resetPersonalAccessTokens(null))
}}
defaultSelectedKeys={[location.pathname]} items={menuItems}/>
</div>
</Col>
{hideMenuUser &&
<Col>
<Dropdown overlay={menuUser} placement="bottomRight" trigger={['click']}>
{createAvatar("large")}
</Dropdown>
</Col>
}
</Row>
</>
);
if (screens.xs === true) {
setHideMenuUser(false);
fs.push({ type: "divider", key: userDividerKey });
fs.push({
label: <Link to="#">{user?.name}</Link>,
icon: createAvatar("small"),
key: userEmailKey,
});
fs.push({
label: (
<Button type="link" block onClick={logoutWithRedirect}>
Logout
</Button>
),
key: userLogoutKey,
});
setMenuItems([...fs]);
return;
}
setMenuItems([...fs]);
setHideMenuUser(true);
}, [screens, currentUser]);
useEffect(() => {
if (
users.length === 0 &&
!isRefreshingUserState &&
window.location.pathname !== "/peers" &&
window.location.pathname !== "/users"
) {
setIsRefreshingUserState(true);
dispatch(
userActions.getUsers.request({
getAccessTokenSilently: getTokenSilently,
payload: null,
})
);
return;
}
if (users.length === 0 && isRefreshingUserState) {
return;
}
let runUser = oidcUser;
if (!oidcUser) {
runUser = idTokenPayload;
}
setIsRefreshingUserState(false);
if (runUser) {
const found = users.find((u) =>
u.is_current ? u.is_current : runUser.sub ? u.id == runUser.sub : false
);
if (found) {
setCurrentUser(found);
}
}
}, [users, oidcUser]);
const showTab = (key: string | undefined, user: User | undefined) => {
if (!user) {
return false;
}
if (user.role?.toLowerCase() === "admin") {
return true;
}
return !adminOnlyTabs.find((t) => t === key);
};
const menuUser = (
<Menu
items={[
{
label: (
<Link to="/users" onClick={openPersonalUserPage}>
{user?.email}
</Link>
),
key: "0",
},
{
label: (
<Link to="/logout" onClick={logoutWithRedirect}>
Logout
</Link>
),
key: "1",
},
]}
/>
);
const createAvatar = (size: AvatarSize) => {
return user?.picture ? (
<Avatar size={size} src={user?.picture} icon={<UserOutlined />} />
) : (
<Avatar size={size}>
{(user?.name || "").slice(0, 1).toUpperCase()}
</Avatar>
);
};
return (
<>
<Row justify="space-evenly" align="middle">
<Col flex="0 1 60px">
<Link id="logo" to="/">
<img alt="logo" style={{ width: "55px" }} src={logo} />
</Link>
</Col>
<Col flex="1 1 auto">
<div>
<Menu
mode="horizontal"
selectable={true}
selectedKeys={[location.pathname]}
onSelect={(e) => {
dispatch(userActions.setUser(null as unknown as User));
dispatch(
personalAccessTokenActions.resetPersonalAccessTokens(null)
);
}}
defaultSelectedKeys={[location.pathname]}
items={menuItems}
/>
</div>
</Col>
{hideMenuUser && (
<Col>
<Dropdown
overlay={menuUser}
placement="bottomRight"
trigger={["click"]}
>
{createAvatar("large")}
</Dropdown>
</Col>
)}
</Row>
</>
);
};
export default Navbar;
File diff suppressed because it is too large. Load diff
+54 -55
View File
@@ -123,7 +123,8 @@ const RouteAddNew = (selectedPeer: any) => {
} else {
setNewRoute(false);
}
}, [route]);
}, [route]);
selectedPeer &&
selectedPeer.notPeerRoutes &&
@@ -361,53 +362,54 @@ const RouteAddNew = (selectedPeer: any) => {
}
};
const styleNotification = { marginTop: 85 };
const saveKey = "saving";
useEffect(() => {
if (savedRoute.loading) {
message.loading({
content: "Saving...",
key: saveKey,
duration: 0,
style: styleNotification,
});
} else if (savedRoute.success) {
message.success({
content: "Route has been successfully added.",
key: saveKey,
duration: 2,
style: styleNotification,
});
dispatch(routeActions.setSetupNewRouteVisible(false));
dispatch(routeActions.setSetupEditRouteVisible(false));
dispatch(routeActions.setSetupEditRoutePeerVisible(false));
dispatch(routeActions.setSavedRoute({ ...savedRoute, success: false }));
dispatch(routeActions.resetSavedRoute(null));
} else if (savedRoute.error) {
let errorMsg = "Failed to update network route";
switch (savedRoute.error.statusCode) {
case 403:
errorMsg =
"Failed to update network route. You might not have enough permissions.";
break;
default:
errorMsg = savedRoute.error.data.message
? savedRoute.error.data.message
: errorMsg;
break;
const styleNotification = { marginTop: 85 };
const saveKey = "saving";
useEffect(() => {
if (savedRoute.loading) {
message.loading({
content: "Saving...",
key: saveKey,
duration: 0,
style: styleNotification,
});
} else if (savedRoute.success) {
message.success({
content: "Route has been successfully added.",
key: saveKey,
duration: 2,
style: styleNotification,
});
dispatch(routeActions.setSetupNewRouteVisible(false));
dispatch(routeActions.setSetupEditRouteVisible(false));
dispatch(routeActions.setSetupEditRoutePeerVisible(false));
dispatch(routeActions.setSavedRoute({ ...savedRoute, success: false }));
dispatch(routeActions.resetSavedRoute(null));
} else if (savedRoute.error) {
let errorMsg = "Failed to update network route";
switch (savedRoute.error.statusCode) {
case 403:
errorMsg =
"Failed to update network route. You might not have enough permissions.";
break;
default:
errorMsg = savedRoute.error.data.message
? savedRoute.error.data.message
: errorMsg;
break;
}
message.error({
content: errorMsg,
key: saveKey,
duration: 5,
style: styleNotification,
});
dispatch(routeActions.setSavedRoute({ ...savedRoute, error: null }));
dispatch(routeActions.resetSavedRoute(null));
}
message.error({
content: errorMsg,
key: saveKey,
duration: 5,
style: styleNotification,
});
dispatch(routeActions.setSavedRoute({ ...savedRoute, error: null }));
dispatch(routeActions.resetSavedRoute(null));
}
}, [savedRoute]);
}, [savedRoute]);
return (
<>
{route && (
@@ -424,7 +426,7 @@ const RouteAddNew = (selectedPeer: any) => {
disabled={savedRoute.loading}
onClick={handleFormSubmit}
>
Add route
Add Route
</Button>
</Space>
}
@@ -453,7 +455,7 @@ const RouteAddNew = (selectedPeer: any) => {
marginBottom: "25px",
}}
>
Add route
Add Route
</Paragraph>
{!!selectedPeer.selectedPeer && (
@@ -732,12 +734,9 @@ const RouteAddNew = (selectedPeer: any) => {
tagRender={blueTagRender}
onChange={handleChangeTags}
dropdownRender={dropDownRender}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option key={index} value={m.id} serchValue={m.name}>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
@@ -888,7 +887,7 @@ const RouteAddNew = (selectedPeer: any) => {
</Col>
<Col
span={24}
style={{ marginTop: "24px", marginBottom: "12px" }}
style={{ marginTop: "20px", marginBottom: "25px" }}
>
<Text type={"secondary"}>
Learn more about
@@ -898,7 +897,7 @@ const RouteAddNew = (selectedPeer: any) => {
href="https://docs.netbird.io/how-to/routing-traffic-to-private-networks"
>
{" "}
network routes
Network Routes
</a>
</Text>
</Col>
+49 -52
View File
@@ -73,7 +73,7 @@ const RoutePeerUpdate = () => {
if (!route) return;
const fRoute = {
...route,
groups: route.groups,
groups: getGroupNamesFromIDs(route.groups),
} as FormRoute;
setFormRoute(fRoute);
form.setFieldsValue(fRoute);
@@ -222,53 +222,53 @@ const RoutePeerUpdate = () => {
onCancel();
};
const styleNotification = { marginTop: 85 };
const styleNotification = { marginTop: 85 };
const saveKey = "saving";
useEffect(() => {
if (savedRoute.loading) {
message.loading({
content: "Saving...",
key: saveKey,
duration: 0,
style: styleNotification,
});
} else if (savedRoute.success) {
message.success({
content: "Route has been successfully updated.",
key: saveKey,
duration: 2,
style: styleNotification,
});
dispatch(routeActions.setSetupNewRouteVisible(false));
dispatch(routeActions.setSetupEditRouteVisible(false));
dispatch(routeActions.setSetupEditRoutePeerVisible(false));
dispatch(routeActions.setSavedRoute({ ...savedRoute, success: false }));
dispatch(routeActions.resetSavedRoute(null));
} else if (savedRoute.error) {
let errorMsg = "Failed to update network route";
switch (savedRoute.error.statusCode) {
case 403:
errorMsg =
"Failed to update network route. You might not have enough permissions.";
break;
default:
errorMsg = savedRoute.error.data.message
? savedRoute.error.data.message
: errorMsg;
break;
const saveKey = "saving";
useEffect(() => {
if (savedRoute.loading) {
message.loading({
content: "Saving...",
key: saveKey,
duration: 0,
style: styleNotification,
});
} else if (savedRoute.success) {
message.success({
content: "Route has been successfully updated.",
key: saveKey,
duration: 2,
style: styleNotification,
});
dispatch(routeActions.setSetupNewRouteVisible(false));
dispatch(routeActions.setSetupEditRouteVisible(false));
dispatch(routeActions.setSetupEditRoutePeerVisible(false));
dispatch(routeActions.setSavedRoute({ ...savedRoute, success: false }));
dispatch(routeActions.resetSavedRoute(null));
} else if (savedRoute.error) {
let errorMsg = "Failed to update network route";
switch (savedRoute.error.statusCode) {
case 403:
errorMsg =
"Failed to update network route. You might not have enough permissions.";
break;
default:
errorMsg = savedRoute.error.data.message
? savedRoute.error.data.message
: errorMsg;
break;
}
message.error({
content: errorMsg,
key: saveKey,
duration: 5,
style: styleNotification,
});
dispatch(routeActions.setSavedRoute({ ...savedRoute, error: null }));
dispatch(routeActions.resetSavedRoute(null));
}
message.error({
content: errorMsg,
key: saveKey,
duration: 5,
style: styleNotification,
});
dispatch(routeActions.setSavedRoute({ ...savedRoute, error: null }));
dispatch(routeActions.resetSavedRoute(null));
}
}, [savedRoute]);
}, [savedRoute]);
return (
<>
<Container style={{ paddingTop: "40px", paddingBottom: "50px" }}>
@@ -291,7 +291,7 @@ const RoutePeerUpdate = () => {
requiredMark={false}
onValuesChange={onChange}
style={{ width: "100%", maxWidth: "600px" }}
className="route-form edit-form-wrapper"
className="route-form"
>
<Row gutter={16}>
<Col span={24}>
@@ -477,12 +477,9 @@ const RoutePeerUpdate = () => {
tagRender={blueTagRender}
onChange={handleChangeTags}
dropdownRender={dropDownRender}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option key={index} value={m.id} serchValue={m.name}>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
+9 -13
View File
@@ -76,7 +76,7 @@ const RouteAddNew = () => {
if (!route) return;
const fRoute = {
...route,
groups: route.groups,
groups: getGroupNamesFromIDs(route.groups),
} as FormRoute;
setFormRoute(fRoute);
setPreviousRouteKey(fRoute.network_id + fRoute.network);
@@ -310,7 +310,7 @@ const RouteAddNew = () => {
disabled={savedRoute.loading}
onClick={handleFormSubmit}
>
Add route
Add Route
</Button>
</Space>
}
@@ -334,7 +334,9 @@ const RouteAddNew = () => {
textAlign: "start",
whiteSpace: "pre-line",
fontSize: "18px",
margin: "0px",
fontWeight: 500,
marginBottom: "0",
}}
>
Add new routing peer
@@ -342,12 +344,9 @@ const RouteAddNew = () => {
<Paragraph
type={"secondary"}
style={{
textAlign: "start",
whiteSpace: "pre-line",
marginTop: "-23px",
fontSize: "14px",
paddingBottom: "25px",
marginBottom: "4px",
marginTop: "-2",
fontWeight: "400",
marginBottom: "25px",
}}
>
When you add multiple routing peers, NetBird enables high
@@ -475,12 +474,9 @@ const RouteAddNew = () => {
tagRender={blueTagRender}
onChange={handleChangeTags}
dropdownRender={dropDownRender}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option key={index} value={m.id} serchValue={m.name}>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
+44 -34
View File
@@ -7,9 +7,11 @@ import {
Divider,
Form,
Input,
InputNumber,
Row,
Select,
Breadcrumb,
Switch,
Tag,
Typography,
Card,
@@ -20,14 +22,15 @@ import {
SetupKey,
SetupKeyToSave,
} from "../store/setup-key/types";
import { formatDate } from "../utils/common";
import { formatDate, timeAgo } from "../utils/common";
import { RuleObject } from "antd/lib/form";
import { CustomTagProps } from "rc-select/lib/BaseSelect";
import { Group } from "../store/group/types";
import { useGetTokenSilently } from "../utils/token";
import moment from "moment";
import { Container } from "./Container";
import Paragraph from "antd/es/typography/Paragraph";
import { LockOutlined } from "@ant-design/icons";
import { EditOutlined, LockOutlined } from "@ant-design/icons";
import { actions as personalAccessTokenActions } from "../store/personal-access-token";
import { useGetGroupTagHelpers } from "../utils/groups";
@@ -39,13 +42,7 @@ const customExpiresFormat = (value: Date): string | null => {
};
const SetupKeyNew = () => {
const {
optionRender,
blueTagRender,
tagGroups,
getExistingAndToCreateGroupsLists,
setGroupTagFilterAll,
} = useGetGroupTagHelpers();
const { optionRender, blueTagRender } = useGetGroupTagHelpers();
const { getTokenSilently } = useGetTokenSilently();
const dispatch = useDispatch();
@@ -53,18 +50,14 @@ const SetupKeyNew = () => {
const savedSetupKey = useSelector(
(state: RootState) => state.setupKey.savedSetupKey
);
const groups = useSelector((state: RootState) => state.group.data);
const [form] = Form.useForm();
const [editName, setEditName] = useState(false);
const [formSetupKey, setFormSetupKey] = useState({} as FormSetupKey);
const [tagGroups, setTagGroups] = useState([] as string[]);
const [formSetupKey, setFormSetupKey] = useState({} as FormSetupKey);
const inputNameRef = useRef<any>(null);
useEffect(() => {
setGroupTagFilterAll(true);
}, []);
useEffect(() => {
//Unmounting component clean
return () => {
@@ -78,6 +71,12 @@ const SetupKeyNew = () => {
inputNameRef.current!.focus({ cursor: "end" });
}, [editName]);
useEffect(() => {
setTagGroups(
groups?.filter((g) => g.name !== "All").map((g) => g.name) || []
);
}, [groups]);
useEffect(() => {
if (!setupKey) return;
@@ -93,25 +92,32 @@ const SetupKeyNew = () => {
const fSetupKey = {
...setupKey,
autoGroupNames: setupKey.auto_groups || [],
autoGroupNames: setupKey.auto_groups ? formKeyGroups : [],
exp: moment(setupKey.expires),
last: moment(setupKey.last_used),
} as FormSetupKey;
form.setFieldsValue(fSetupKey);
setFormSetupKey(fSetupKey);
}, [setupKey]);
const createSetupKeyToSave = (): SetupKeyToSave => {
let [existingGroups, groupsToCreate] = getExistingAndToCreateGroupsLists(
formSetupKey.autoGroupNames
const autoGroups =
groups
?.filter((g) => formSetupKey.autoGroupNames.includes(g.name))
.map((g) => g.id || "") || [];
// find groups that do not yet exist (newly added by the user)
const allGroupsNames: string[] = groups?.map((g) => g.name);
const groupsToCreate = formSetupKey.autoGroupNames.filter(
(s) => !allGroupsNames.includes(s)
);
const expiresIn = formSetupKey.expires_in * 24 * 3600; // the api expects seconds while the form returns days
const expiresIn = formSetupKey.expires_in * 24 * 3600 // the api expects seconds while the form returns days
return {
id: formSetupKey.id,
name: formSetupKey.name,
type: formSetupKey.type,
auto_groups: existingGroups,
auto_groups: autoGroups,
revoked: formSetupKey.revoked,
groupsToCreate: groupsToCreate,
expires_in: expiresIn,
@@ -269,13 +275,7 @@ const SetupKeyNew = () => {
/>
<Card bordered={true} style={{ marginBottom: "7px", border: "none" }}>
<div style={{ maxWidth: "800px" }}>
<h3
style={{
fontSize: "22px",
fontWeight: "500",
marginBottom: "30px",
}}
>
<h3 style={{ fontSize: "22px", fontWeight: "500",marginBottom:"30px" }}>
{setupKey.name}
</h3>
<Form
@@ -361,7 +361,7 @@ const SetupKeyNew = () => {
</Col>
</Row>
<Row style={{ marginTop: "39px" }}>
<Row style={{ marginTop: "30px" }}>
<Col
xs={24}
sm={24}
@@ -396,12 +396,9 @@ const SetupKeyNew = () => {
dropdownRender={dropDownRender}
// enabled only when we have a new key !setupkey.id or when the key is valid
disabled={!(!setupKey.id || setupKey.valid)}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option key={index} value={m.id} serchValue={m.name}>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
@@ -422,6 +419,20 @@ const SetupKeyNew = () => {
</Row>
</Col>
</Row>
<Row style={{ marginTop: "40px", marginBottom: "28px" }}>
<Text type={"secondary"}>
Learn more about
<a
target="_blank"
rel="noreferrer"
href="https://docs.netbird.io/how-to/register-machines-using-setup-keys"
>
{" "}
Setup Keys
</a>
</Text>
</Row>
</Form>
</div>
<Container
@@ -431,7 +442,6 @@ const SetupKeyNew = () => {
justifyContent: "start",
padding: 0,
gap: "10px",
marginTop: "24px",
}}
key={0}
>
+67 -52
View File
@@ -11,7 +11,9 @@ import {
Modal,
Row,
Select,
Space,
Switch,
Tag,
Typography,
} from "antd";
import { RootState } from "typesafe-actions";
@@ -21,24 +23,21 @@ import {
SetupKeyToSave,
} from "../store/setup-key/types";
import { RuleObject } from "antd/lib/form";
import { CustomTagProps } from "rc-select/lib/BaseSelect";
import { Group } from "../store/group/types";
import { useGetTokenSilently } from "../utils/token";
import moment from "moment";
import { Container } from "./Container";
import Paragraph from "antd/es/typography/Paragraph";
import { CheckOutlined, CopyOutlined } from "@ant-design/icons";
import { copyToClipboard } from "../utils/common";
import { useGetGroupTagHelpers } from "../utils/groups";
import {useGetGroupTagHelpers} from "../utils/groups";
const { Option } = Select;
const { Text } = Typography;
const SetupKeyNew = () => {
const {
optionRender,
blueTagRender,
tagGroups,
getExistingAndToCreateGroupsLists,
setGroupTagFilterAll,
} = useGetGroupTagHelpers();
const { optionRender, blueTagRender } = useGetGroupTagHelpers();
const { getTokenSilently } = useGetTokenSilently();
const dispatch = useDispatch();
const setupNewKeyVisible = useSelector(
@@ -55,6 +54,7 @@ const SetupKeyNew = () => {
const [showPlainToken, setShowPlainToken] = useState(false);
const [plainToken, setPlainToken] = useState("");
const [tokenCopied, setTokenCopied] = useState(false);
const [tagGroups, setTagGroups] = useState([] as string[]);
const [formSetupKey, setFormSetupKey] = useState({} as FormSetupKey);
const inputNameRef = useRef<any>(null);
@@ -65,21 +65,52 @@ const SetupKeyNew = () => {
}, [editName]);
useEffect(() => {
setGroupTagFilterAll(true);
}, []);
setTagGroups(
groups?.filter((g) => g.name !== "All").map((g) => g.name) || []
);
}, [groups]);
useEffect(() => {
if (!setupKey) return;
const allGroups = new Map<string, Group>();
let formKeyGroups: string[] = [];
groups.forEach((g) => allGroups.set(g.id!, g));
if (setupKey.auto_groups) {
formKeyGroups = setupKey.auto_groups
.filter((g) => allGroups.get(g))
.map((g) => allGroups.get(g)!.name);
}
const fSetupKey = {
...setupKey,
autoGroupNames: setupKey.auto_groups ? formKeyGroups : [],
exp: moment(setupKey.expires),
last: moment(setupKey.last_used),
} as FormSetupKey;
form.setFieldsValue(fSetupKey);
setFormSetupKey(fSetupKey);
}, [setupKey]);
const createSetupKeyToSave = (): SetupKeyToSave => {
let [existingGroups, groupsToCreate] = getExistingAndToCreateGroupsLists(
formSetupKey.autoGroupNames || []
const autoGroups =
groups
?.filter((g) => formSetupKey.autoGroupNames.includes(g.name))
.map((g) => g.id || "") || [];
// find groups that do not yet exist (newly added by the user)
const allGroupsNames: string[] = groups?.map((g) => g.name);
const groupsToCreate = formSetupKey.autoGroupNames.filter(
(s) => !allGroupsNames.includes(s)
);
const expiresIn = formSetupKey.expires_in
? formSetupKey.expires_in * 24 * 3600
: 7 * 24 * 3600; // the api expects seconds we have days
const expiresIn = formSetupKey.expires_in * 24 * 3600 // the api expects seconds we have days
return {
id: formSetupKey.id,
name: formSetupKey.name,
type: formSetupKey.type ? formSetupKey.type : "one-off",
auto_groups: existingGroups,
type: formSetupKey.type,
auto_groups: autoGroups,
revoked: formSetupKey.revoked,
groupsToCreate: groupsToCreate,
expires_in: expiresIn,
@@ -149,7 +180,7 @@ const SetupKeyNew = () => {
type: "one-off",
key: "",
last_used: "",
expires: "7",
expires: "",
state: "valid",
auto_groups: [] as string[],
usage_limit: 0,
@@ -220,27 +251,25 @@ const SetupKeyNew = () => {
);
const changesDetected = (): boolean => {
console.log("formSetupKey", formSetupKey);
return (
formSetupKey.name == null ||
formSetupKey.name !== setupKey.name ||
formSetupKey?.usage_limit !== setupKey.usage_limit
groupsChanged() ||
formSetupKey.usage_limit !== setupKey.usage_limit
);
};
const groupsChanged = (): boolean => {
console.log("groupsChanged", formSetupKey);
if (
setupKey &&
setupKey?.auto_groups &&
formSetupKey?.autoGroupNames &&
formSetupKey?.autoGroupNames.length !== setupKey?.auto_groups.length
setupKey.auto_groups &&
formSetupKey.autoGroupNames.length !== setupKey.auto_groups.length
) {
return true;
}
const formGroupIds =
groups
?.filter((g) => formSetupKey?.autoGroupNames.includes(g.name))
?.filter((g) => formSetupKey.autoGroupNames.includes(g.name))
.map((g) => g.id || "") || [];
return (
@@ -285,7 +314,7 @@ const SetupKeyNew = () => {
fontSize: "14px",
borderRadius: "2px",
}}
disabled={savedSetupKey.loading || !!!formSetupKey.name}
disabled={savedSetupKey.loading || !changesDetected()}
onClick={handleFormSubmit}
>
Create key
@@ -316,7 +345,8 @@ const SetupKeyNew = () => {
textAlign: "start",
whiteSpace: "pre-line",
fontSize: "18px",
fontWeight: "500",
margin: "0px",
fontWeight:"500"
}}
>
{showPlainToken
@@ -328,10 +358,6 @@ const SetupKeyNew = () => {
style={{
textAlign: "start",
whiteSpace: "pre-line",
marginTop: "-20px",
fontSize: "14px",
paddingBottom: "25px",
marginBottom: "4px",
}}
>
{showPlainToken
@@ -346,7 +372,6 @@ const SetupKeyNew = () => {
onValuesChange={onChange}
initialValues={{
usage_limit: 1,
expires_in: "7",
}}
>
<Row>
@@ -373,7 +398,7 @@ const SetupKeyNew = () => {
</Col>
</Row>
<Row style={{ marginTop: "24px" }} justify={"space-between"}>
<Row style={{ marginTop: "20px" }} justify={"space-between"}>
<Col span={18}>
<Paragraph
style={{
@@ -395,7 +420,6 @@ const SetupKeyNew = () => {
<Row justify={"end"}>
<Form.Item name="reusable" valuePropName="checked">
<Switch
size="small"
onChange={(checked) => {
setFormSetupKey({
...formSetupKey,
@@ -408,7 +432,7 @@ const SetupKeyNew = () => {
</Col>
</Row>
<Row style={{ marginTop: "16px" }}>
<Row style={{ marginTop: "10px" }}>
<Col span={24}>
<Paragraph
style={{
@@ -446,7 +470,7 @@ const SetupKeyNew = () => {
</Col>
</Row>
<Row style={{ marginTop: "24px" }}>
<Row style={{ marginTop: "20px" }}>
<Col span={24}>
<Paragraph
style={{
@@ -462,13 +486,6 @@ const SetupKeyNew = () => {
<Form.Item
name="expires_in"
rules={[
{
type: "number",
min: 1,
max: 365,
message:
"The expiration should be set between 1 and 365 days",
},
{ required: true, message: "Please enter expiration date" },
]}
>
@@ -483,12 +500,12 @@ const SetupKeyNew = () => {
type={"secondary"}
style={{ marginTop: "-18px", marginBottom: 0 }}
>
Should be between 1 and 365 days
Should be between 1 and 180 days
</Paragraph>
</Col>
</Row>
<Row style={{ marginTop: "24px" }}>
<Row style={{ marginTop: "20px" }}>
<Col span={24}>
<Paragraph
style={{
@@ -508,27 +525,25 @@ const SetupKeyNew = () => {
<Form.Item
style={{ marginTop: "5px", marginBottom: 0 }}
name="autoGroupNames"
rules={[{ validator: selectValidator }]}
>
<Select
mode="tags"
style={{ width: "100%" }}
style={{ width: "100%"}}
placeholder="Associate groups with the key"
tagRender={blueTagRender}
dropdownRender={dropDownRender}
// enabled only when we have a new key !setupkey.id or when the key is valid
disabled={!(!setupKey.id || setupKey.valid)}
optionFilterProp="serchValue"
>
{tagGroups.map((m, index) => (
<Option key={index} value={m.id} serchValue={m.name}>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
</Col>
</Row>
<Row style={{ marginTop: "24px", marginBottom: "24px" }}>
<Row style={{ marginTop: "40px", marginBottom: "28px" }}>
<Text type={"secondary"}>
Learn more about
<a
-21
View File
@@ -1,21 +0,0 @@
import React, { useEffect, useState } from "react";
import { Modal } from "antd";
import PeerUpdate from "./PeerUpdate";
export const UpdatePeerGroupModal = (props:any) => {
return (
<>
<Modal
closable={false}
open={true}
footer={[]}
onCancel={() => props.setShowGroupModal(false)}
width={450}
>
<PeerUpdate
isGroupUpdateView={true}
setShowGroupModal={props.setShowGroupModal}
/>
</Modal>
</>
);
};
File diff suppressed because it is too large. Load diff
+3 -12
View File
@@ -177,18 +177,9 @@ const AddPATPopup = () => {
</Form.Item>
<Paragraph type={"secondary"} style={{fontSize: "14px", marginTop: "-18px"}}>Should be between 1 and 365 days</Paragraph>
</Col>
<Col span={24} style={{marginTop: "15px"}}>
<Text type={"secondary"}>
Learn more about
<a
target="_blank"
rel="noreferrer"
href="https://docs.netbird.io/how-to/access-netbird-public-api"
>
{" "}
access tokens
</a>
</Text>
<Col span={24}>
<Button icon={<QuestionCircleFilled/>} type="link" target="_blank" disabled={true} style={{marginTop: "20px", marginBottom: "20px"}}
href="https://docs.netbird.io/how-to/access-netbird-public-api">Learn more about personal access tokens</Button>
</Col>
</Row>
</Form>}
+34 -35
View File
@@ -8,10 +8,11 @@ import {
Row,
Select,
Space,
Tag,
Typography,
} from "antd";
import { Container } from "../Container";
import React, { useEffect, useRef } from "react";
import React, { useEffect, useRef, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "typesafe-actions";
import { useGetTokenSilently } from "../../utils/token";
@@ -27,8 +28,7 @@ const { Title, Text, Paragraph } = Typography;
const { Option } = Select;
const InviteUserPopup = () => {
const { optionRender, blueTagRender, tagGroups, handleChangeTags } =
useGetGroupTagHelpers();
const { optionRender, blueTagRender } = useGetGroupTagHelpers();
const { getTokenSilently } = useGetTokenSilently();
const dispatch = useDispatch();
@@ -48,16 +48,19 @@ const InviteUserPopup = () => {
const [form] = Form.useForm();
const inputNameRef = useRef<any>(null);
const [tagGroups, setTagGroups] = useState([] as string[]);
const [selectedTagGroups, setSelectedTagGroups] = useState([] as string[]);
const createUserToSave = (values: any): UserToSave => {
const autoGroups =
groups
?.filter(
(g) =>
values.autoGroupsNames && values.autoGroupsNames.includes(g.id)
values.autoGroupsNames && values.autoGroupsNames.includes(g.name)
)
.map((g) => g.id || "") || [];
// find groups that do not yet exist (newly added by the user)
const allGroupsNames: string[] = groups?.map((g) => g.id || "");
const allGroupsNames: string[] = groups?.map((g) => g.name);
const groupsToCreate =
values.autoGroupsNames?.filter(
(s: string) => !allGroupsNames.includes(s)
@@ -127,15 +130,15 @@ const InviteUserPopup = () => {
return Promise.resolve();
};
// const handleChangeTags = (value: string[]) => {
// let validatedValues: string[] = [];
// value.forEach(function (v) {
// if (v.trim().length) {
// validatedValues.push(v);
// }
// });
// setSelectedTagGroups(validatedValues);
// };
const handleChangeTags = (value: string[]) => {
let validatedValues: string[] = [];
value.forEach(function (v) {
if (v.trim().length) {
validatedValues.push(v);
}
});
setSelectedTagGroups(validatedValues);
};
const dropDownRender = (menu: React.ReactElement) => (
<>
@@ -165,11 +168,11 @@ const InviteUserPopup = () => {
</>
);
// useEffect(() => {
// setTagGroups(
// groups?.filter((g) => g.name != "All").map((g) => g.name) || []
// );
// }, [groups]);
useEffect(() => {
setTagGroups(
groups?.filter((g) => g.name != "All").map((g) => g.name) || []
);
}, [groups]);
useEffect(() => {
dispatch(
@@ -331,29 +334,25 @@ const InviteUserPopup = () => {
placeholder="Associate groups with the user"
tagRender={blueTagRender}
onChange={handleChangeTags}
optionFilterProp="serchValue"
dropdownRender={dropDownRender}
>
{tagGroups.map((m, index) => (
<Option key={index} value={m.id} serchValue={m.name}>
{optionRender(m.name, m.id)}
</Option>
{tagGroups.map((m) => (
<Option key={m}>{optionRender(m)}</Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={24}>
<Text type={"secondary"}>
Learn more about
<a
target="_blank"
rel="noreferrer"
href="https://docs.netbird.io/how-to/add-users-to-your-network"
>
{" "}
user management
</a>
</Text>
<Button
icon={<QuestionCircleFilled />}
type="link"
target="_blank"
disabled={true}
style={{ marginTop: "20px", marginBottom: "20px" }}
href="https://docs.netbird.io/how-to/access-netbird-public-api"
>
Learn more about user
</Button>
</Col>
</Row>
</Form>
+1 -2
View File
@@ -11,6 +11,5 @@
"hotjarTrackID": "$NETBIRD_HOTJAR_TRACK_ID",
"redirectURI": "$AUTH_REDIRECT_URI",
"silentRedirectURI": "$AUTH_SILENT_REDIRECT_URI",
"tokenSource": "$NETBIRD_TOKEN_SOURCE",
"dragQueryParams": "$NETBIRD_DRAG_QUERY_PARAMS"
"tokenSource": "$NETBIRD_TOKEN_SOURCE"
}
-2
View File
@@ -39,7 +39,5 @@ export function getConfig() {
redirectURI: redirectURI,
silentRedirectURI: silentRedirectURI,
tokenSource: tokenSource,
// drags all the query params to the auth layer specified in the URL when accessing dashboard.
dragQueryParams: configJson.dragQueryParams == "true"
};
}
Loaded 20 of 38 files, more files were not shown because too many files have changed in this diff. Show more