Compare commits

..
Author SHA1 Message Date
Pascal Fischer 1b103ba0f1 change bidirectional tag 2023-05-17 13:50:31 +02:00
Pascal Fischer 9fa1b4d568 gold tag 2023-05-15 17:52:32 +02:00
Pascal Fischer 0695ebd080 Merge branch 'main' into feature/darkmode 2023-05-15 17:44:30 +02:00
Pascal Fischer ca822d428e more rules 2023-05-15 16:20:57 +02:00
Pascal Fischer c49e766b92 Merge branch 'main' into feature/darkmode 2023-05-15 15:05:44 +02:00
Pascal Fischer 07cff534e8 more rules 2023-05-15 13:44:08 +02:00
Pascal Fischer 71f1745b82 more rules 2023-05-14 14:52:51 +02:00
Pascal Fischer ac428a0044 more rules 2023-05-14 14:34:54 +02:00
Pascal Fischer 1de8538884 more rules 2023-05-14 14:33:01 +02:00
Pascal Fischer cec15f6471 add more darkmode 2023-05-13 04:26:45 +02:00
Pascal Fischer 87425f80a4 add more darkmode 2023-05-13 04:21:05 +02:00
Pascal Fischer 39c56ab22e Merge branch 'main' into feature/darkmode 2023-05-12 23:36:31 +02:00
Pascal Fischer 571c2a6e64 fix dropdown button in lists to only show ellipsis 2023-05-12 22:07:09 +02:00
Pascal Fischer 8bb421abcd reduce api calls on user edit 2023-05-10 13:36:00 +02:00
121 changed files with 10406 additions and 22640 deletions

No files matched your search

+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
node-version: '16'
cache: 'npm'
- name: Install dependencies
- name: Install dependecies
run: npm install
- name: Build
-15
View File
@@ -1,15 +0,0 @@
name: Codespell
on: [pull_request]
jobs:
check:
name: Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: codespell
uses: codespell-project/actions-codespell@v2
with:
only_warn: 1
skip: package-lock.json,*.svg
-42
View File
@@ -1,42 +0,0 @@
name: run e2e tests
on:
push:
branches:
- main
pull_request:
jobs:
e2e_tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: setup-node
uses: actions/setup-node@v3
with:
node-version: '16'
cache: 'npm'
- name: Install dependencies
run: npm install
- name: install playwright
run: npx playwright install
- name: install playwright deps
run: npx playwright install-deps
- name: create test environment
run: bash ./e2e-tests/create-test-env.sh
- name: run e2e tests
run: npx playwright test --workers 2
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: |
playwright-report/
test-results/
retention-days: 3
+1 -13
View File
@@ -26,18 +26,6 @@ yarn-error.log*
src/auth_config.json
.idea
.eslintcache
src/.local-config*.json
src/.local-config.json
/public/OidcServiceWorker.js
/public/OidcTrustedDomains.js
/e2e-tests/node_modules/
/e2e-tests/playwright-report/
/e2e-tests/test-results/
/test-results/
/playwright-report/
.env
Caddyfile
docker-compose.yml
machinekey/
management.json
turnserver.conf
zitadel.env
+3 -3
View File
@@ -1,15 +1,15 @@
# Wiretrustee Dashboard
Wiretrustee Dashboard is a the Wiretrustee Management server UI. It allow users to signin, view setup keys and manage peers. This image is **not ready** for production use.
Wiretrustee Dashboard is a the Wiretrustee Managemenet server UI. It allow users to signin, view setup keys and manage peers. This image is **not ready** for production use.
## Tags
```latest``` ```vX.X.X``` not available yet.
```main``` built on every PR being merged to the repository
```main``` builded on every PR being merged to the repository
## How to use this image
HTTP run:
```shell
docker run -d --rm -p 80:80 wiretrustee/dashboard:main
```
Using SSL certificate from Let's Encrypt®:
Using SSL certificate from Let's Encript®:
```shell
docker run -d --rm -p 80:80 -p 443:443 \
-e LETSENCRYPT_DOMAIN=app.mydomain.com \
+1 -7
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"
@@ -47,7 +43,6 @@ 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}
@@ -58,12 +53,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_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"
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
docker-compose down --volumes
rm -f docker-compose.yml Caddyfile zitadel.env dashboard.env machinekey/zitadel-admin-sa.token turnserver.conf management.json
File diff suppressed because it is too large. Load diff
-56
View File
@@ -1,56 +0,0 @@
import { Page, test, expect } from "@playwright/test";
export class AccessControlPage {
private readonly accessControlUrl = 'http://localhost:3000/acls'
private readonly defaulAccessControl = this.page.getByRole('cell', { name: 'Default' })
private readonly deleteButton = this.page.getByRole('button', { name: 'Delete' })
private readonly deleteModal = this.page.getByTestId('confirm-delete-modal-title')
private readonly confirmButton = this.page.getByRole('button', { name: 'OK' })
private readonly addRulesButton = this.page.getByTestId('add-rule-empty-state-button')
constructor(private readonly page: Page) {}
async openAccessControlPage() {
await test.step('Open Access Control page', async () => {
await this.page.goto(this.accessControlUrl);
})
}
async assertDefaultAccessCotrolIsCreated() {
await test.step('Assert that default control access is created', async () => {
await expect(this.defaulAccessControl).toBeVisible();
})
}
async pressDeleteButton() {
await test.step('Press delete button', async () => {
await this.deleteButton.click();
})
}
async assertDeleteModalIsVisibile() {
await test.step('Assert access control deletion modal is visible', async () => {
await expect(this.deleteModal).toBeVisible();
})
}
async pressConfirmButton() {
await test.step('Press confirm button on access control deletion modal', async () => {
await this.confirmButton.click();
})
}
async assertDefaultAccessCotrolIsDeleted() {
await test.step('Assert default access control should be deleted', async () => {
await expect(this.defaulAccessControl).not.toBeVisible();
})
}
async assertAddRuleButtonIsVisile() {
await test.step('Assert Add Rules button is visible', async () => {
await expect(this.addRulesButton).toBeVisible();
})
}
}
export default AccessControlPage;
-34
View File
@@ -1,34 +0,0 @@
import { Page, test, expect} from "@playwright/test";
export class LoginPage {
private readonly localUrl = 'http://localhost:3000/'
private readonly usernameField = this.page.getByPlaceholder('username@domain')
private readonly nextButton = this.page.getByRole('button', { name: 'next' })
private readonly passwordField = this.page.getByLabel('Password')
private readonly skipButton = this.page.getByRole('button', { name: 'skip' });
private readonly netBirdLogo = this.page.getByRole('link', { name: 'logo' })
constructor(private readonly page: Page) {}
async doLogin() {
await test.step('Login to local enviroment', async () => {
await this.page.goto(this.localUrl);
await this.usernameField.fill('admin@localhost');
await this.pressNextButton();
await this.passwordField.fill('testMe123@');
await this.pressNextButton();
if (await this.skipButton.isVisible({ timeout: 300 })) {
await this.skipButton.click();
}
await expect(this.netBirdLogo).toBeVisible();
})
}
async pressNextButton() {
await test.step('Press next button', async () => {
await this.nextButton.click();
})
}
}
export default LoginPage;
-111
View File
@@ -1,111 +0,0 @@
import { Page, test, expect } from "@playwright/test";
export class AddPeerModal {
private readonly addPeerModal = this.page.getByTestId('add-peer-modal').locator('div').nth(2)
private readonly linuxTab = this.page.getByTestId('add-peer-modal-linux-tab')
private readonly windowsTab = this.page.getByTestId('add-peer-modal-windows-tab')
private readonly macTab = this.page.getByTestId('add-peer-modal-mac-tab')
private readonly androidTab = this.page.getByTestId('add-peer-modal-android-tab')
private readonly dockerTab = this.page.getByTestId('add-peer-modal-docker-tab')
private readonly linuxTabText = this.page.locator('pre').filter({ hasText: 'curl -fsSL https://pkgs.netbird.io/install.sh | sh' })
private readonly windowsDownloadButton = this.page.getByTestId('download-windows-button')
private readonly intelDownloadButton = this.page.getByTestId('download-intel-button')
private readonly m1M2DownloadButton = this.page.getByTestId('download-m1-m2-button')
private readonly androidDownloadButton = this.page.getByTestId('download-android-button')
private readonly dockerDownloadButton = this.page.getByTestId('download-docker-button')
private readonly closeButton = this.page.getByLabel('Close', { exact: true })
constructor(private readonly page: Page) {}
async assertPeerModalIsVisible() {
await test.step('Assert that add peer modal is visible', async () => {
await expect(this.addPeerModal).toBeVisible();
})
}
async assertPeerModalIsNotVisible() {
await test.step('Assert that add peer modal is not visible', async () => {
await expect(this.addPeerModal).not.toBeVisible();
})
}
async openLinuxTab() {
await test.step('Open Linux tab on add peer modal', async () => {
await this.linuxTab.click();
})
}
async openWindowsTab() {
await test.step('Open Windows tab on add peer modal', async () => {
await this.windowsTab.click();
})
}
async openMacTab() {
await test.step('Open MacOS tab on add peer modal', async () => {
await this.macTab.click();
})
}
async openAndroidTab() {
await test.step('Open Android tab on add peer modal', async () => {
await this.androidTab.click();
})
}
async openDockerTab() {
await test.step('Open Docker tab on add peer modal', async () => {
await this.dockerTab.click();
})
}
async assertLinuxTabHasCorrectText() {
await test.step('Assert Linux tab has correct installation text', async () => {
await expect(this.linuxTabText).toBeVisible();
})
}
async assertWindowsDownloadButtonHasCorrectLink() {
await test.step('Assert Windows download button has a correct link', async () => {
await expect(this.windowsDownloadButton).toHaveAttribute('href', 'https://pkgs.netbird.io/windows/x64');
})
}
async assertIntelDownloadButtonHasCorrectLink() {
await test.step('Assert Intel download button has a correct link', async () => {
await expect(this.intelDownloadButton).toHaveAttribute('href', 'https://pkgs.netbird.io/macos/amd64');
})
}
async assertM1M2DownloadButtonHasCorrectLink() {
await test.step('Assert M1 & M2 download button has a correct link', async () => {
await expect(this.m1M2DownloadButton).toHaveAttribute('href', 'https://pkgs.netbird.io/macos/arm64');
})
}
async assertAndroidDownloadButtonHasCorrectLink() {
await test.step('Assert Android download button has a correct link', async () => {
await expect(this.androidDownloadButton).toHaveAttribute('href', 'https://play.google.com/store/apps/details?id=io.netbird.client');
})
}
async assertDockerDownloadButtonHasCorrectLink() {
await test.step('Assert Docker download button has a correct link', async () => {
await expect(this.dockerDownloadButton).toHaveAttribute('href', 'https://docs.docker.com/engine/install/');
})
}
async closeAddPeerModal() {
await test.step('Close Add peer modal', async () => {
await this.closeButton.click();
})
}
}
export default AddPeerModal;
-15
View File
@@ -1,15 +0,0 @@
import { Page, test } from "@playwright/test";
export class PeersPage {
private readonly addNewPeerButton = this.page.getByTestId('add-new-peer-button')
constructor(private readonly page: Page) {}
async clickOnAddNewPeerButton() {
await test.step('Click on Add new peer Button to open Add peer modal', async () => {
await this.addNewPeerButton.click();
})
}
}
export default PeersPage;
-15
View File
@@ -1,15 +0,0 @@
import { Page, test} from "@playwright/test";
export class TopMenu {
private readonly accessControlButton = this.page.getByTestId('access-control-page')
constructor(private readonly page: Page) {}
async clickOnAccessControlOnTopMenu() {
await test.step('Click on Access Control page on a top menu', async () => {
await this.accessControlButton.click();
})
}
}
export default TopMenu;
-22
View File
@@ -1,22 +0,0 @@
import { test } from '@playwright/test'
import {LoginPage} from '../pages/login-page'
import {AccessControlPage} from '../pages/access-control-page'
let loginPage: LoginPage
let accessControlPage: AccessControlPage
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
await loginPage.doLogin();
});
test('Confirm that new user has Default access', async ({ page }) => {
accessControlPage = new AccessControlPage(page);
await accessControlPage.openAccessControlPage();
await accessControlPage.assertDefaultAccessCotrolIsCreated();
await accessControlPage.pressDeleteButton();
await accessControlPage.assertDeleteModalIsVisibile();
await accessControlPage.pressConfirmButton();
await accessControlPage.assertDefaultAccessCotrolIsDeleted();
await accessControlPage.assertAddRuleButtonIsVisile();
});
-49
View File
@@ -1,49 +0,0 @@
import { test } from '@playwright/test'
import {AddPeerModal} from '../pages/modals/add-peer-modal'
import {PeersPage} from '../pages/peers-page'
import {LoginPage} from '../pages/login-page'
let addPeerModal: AddPeerModal
let peersPage: PeersPage
let loginPage: LoginPage
test.beforeEach(async ({ page }) => {
addPeerModal = new AddPeerModal(page);
loginPage = new LoginPage(page);
await loginPage.doLogin();
await addPeerModal.assertPeerModalIsVisible();
});
test('Test Linux tab on a first access add peer modal / @bc', async function () {
await addPeerModal.openLinuxTab();
await addPeerModal.assertLinuxTabHasCorrectText();
});
test('Test Windows tab on a first access add peer modal / @bc', async () => {
await addPeerModal.openWindowsTab();
await addPeerModal.assertWindowsDownloadButtonHasCorrectLink();
});
test('Test MacOS tab on a first access add peer modal / @bc', async () => {
await addPeerModal.openMacTab();
await addPeerModal.assertIntelDownloadButtonHasCorrectLink();
await addPeerModal.assertM1M2DownloadButtonHasCorrectLink();
});
test('Test Android tab on a first access add peer modal', async () => {
await addPeerModal.openAndroidTab();
await addPeerModal.assertAndroidDownloadButtonHasCorrectLink();
});
test('Test Docker tab on a first access add peer modal', async () => {
await addPeerModal.openDockerTab();
await addPeerModal.assertDockerDownloadButtonHasCorrectLink();
});
test('Close and open Add peer modal', async ({ page }) => {
peersPage = new PeersPage(page);
await addPeerModal.closeAddPeerModal();
await addPeerModal.assertPeerModalIsNotVisible();
await peersPage.clickOnAddNewPeerButton();
await addPeerModal.assertPeerModalIsVisible();
});
+172 -544
View File
File diff suppressed because it is too large. Load diff
+2 -3
View File
@@ -39,7 +39,6 @@
"react-redux": "^8.0.2",
"react-router-dom": "^5.3.3",
"react-scripts": "^5.0.1",
"react-select": "^5.7.3",
"react-syntax-highlighter": "^15.5.0",
"react-table": "^7.7.0",
"redux": "^4.2.0",
@@ -79,7 +78,7 @@
]
},
"devDependencies": {
"@types/react-syntax-highlighter": "^15.5.3",
"@playwright/test": "^1.36.2"
"@tailwindcss/typography": "^0.5.9",
"@types/react-syntax-highlighter": "^15.5.3"
}
}
-80
View File
@@ -1,80 +0,0 @@
import { defineConfig, devices } from '@playwright/test';
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './e2e-tests/tests',
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://127.0.0.1:3000',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { channel: 'chrome', },
},
// {
// name: 'firefox',
// use: { browserName: 'firefox', },
// },
//
// {
// name: 'webkit',
// use: { browserName: 'webkit', },
// },
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],
/* Run your local dev server before starting the tests */
webServer: {
command: 'npm run start',
url: 'http://127.0.0.1:3000',
reuseExistingServer: !process.env.CI,
timeout: 180 * 1000,
},
});
+3
View File
@@ -1,6 +1,9 @@
module.exports = {
plugins: {
tailwindcss: {},
'postcss-focus-visible': {
replaceWith: '[data-focus-visible-added]',
},
autoprefixer: {},
},
}
+13 -2
View File
@@ -22,7 +22,7 @@ import {SecureLoading} from "./components/Loading";
import DNS from "./views/DNS";
import Activity from "./views/Activity";
import Settings from "./views/Settings";
import './styles/tailwind.css'
const {Header, Content} = Layout;
@@ -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>
</>
)
}
Loaded 20 of 121 files, more files were not shown because too many files have changed in this diff. Show more