From c6341e000f569268ea7da9cbe0137ba31fb574c2 Mon Sep 17 00:00:00 2001
From: raghvendra <35917821+fork-boy@users.noreply.github.com>
Date: Mon, 9 Feb 2026 09:11:09 +0530
Subject: [PATCH 1/4] docs: fix broken Auth0 quickstart link in README (#548)
* docs: fix broken Auth0 quickstart link
* docs: spell error fixes in readme
* docs: fix typo in NETBIRD_MGMT_API_ENDPOINT placeholder in readme
---
README.md | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index a134fae0..6c5ddb5d 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@ See [NetBird repo](https://github.com/netbirdio/netbird)
The purpose of this project is simple - make it easy to manage VPN built with [NetBird](https://github.com/netbirdio/netbird).
The dashboard makes it possible to:
+
- track the status of your peers
- remove peers
- manage Setup Keys (to authenticate new peers)
@@ -17,10 +18,10 @@ The dashboard makes it possible to:
- define access controls
## Some Screenshots
+
-
## Technologies Used
- NextJS
@@ -33,8 +34,9 @@ The dashboard makes it possible to:
- Let's Encrypt
## How to run
+
Disclaimer. We believe that proper user management system is not a trivial task and requires quite some effort to make it right. Therefore we decided to
-use Auth0 service that covers all our needs (user management, social login, JTW for the management API).
+use Auth0 service that covers all our needs (user management, social login, JWT for the management API).
Auth0 so far is the only 3rd party dependency that can't be really self-hosted.
1. Install [Docker](https://docs.docker.com/get-docker/)
@@ -43,9 +45,9 @@ Auth0 so far is the only 3rd party dependency that can't be really self-hosted.
`AUTH0_DOMAIN` `AUTH0_CLIENT_ID` `AUTH0_AUDIENCE`
- To obtain these, please use [Auth0 React SDK Guide](https://auth0.com/docs/quickstart/spa/react/01-login#configure-auth0) up until "Configure Allowed Web Origins"
+ To obtain these, please use [Auth0 React SDK Guide](https://auth0.com/docs/quickstart/spa/react) up until "Configure Allowed Web Origins"
-4. NetBird UI Dashboard uses NetBirds Management Service HTTP API, so setting `NETBIRD_MGMT_API_ENDPOINT` is required. Most likely it will be `http://localhost:33071` if you are hosting Management API on the same server.
+4. NetBird UI Dashboard uses NetBird's Management Service HTTP API, so setting `NETBIRD_MGMT_API_ENDPOINT` is required. Most likely it will be `http://localhost:33071` if you are hosting Management API on the same server.
5. Run docker container without SSL (Let's Encrypt):
```shell
@@ -54,9 +56,10 @@ Auth0 so far is the only 3rd party dependency that can't be really self-hosted.
-e AUTH0_DOMAIN= \
-e AUTH0_CLIENT_ID= \
-e AUTH0_AUDIENCE= \
- -e NETBIRD_MGMT_API_ENDPOINT= \
+ -e NETBIRD_MGMT_API_ENDPOINT= \
netbirdio/dashboard:main
```
+
6. Run docker container with SSL (Let's Encrypt):
```shell
@@ -68,7 +71,7 @@ Auth0 so far is the only 3rd party dependency that can't be really self-hosted.
-e AUTH0_DOMAIN= \
-e AUTH0_CLIENT_ID= \
-e AUTH0_AUDIENCE= \
- -e NETBIRD_MGMT_API_ENDPOINT= \
+ -e NETBIRD_MGMT_API_ENDPOINT= \
netbirdio/dashboard:main
```
@@ -84,11 +87,11 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the
You can start editing by modifying the code inside `src/..`
The page auto-updates as you edit the file.
-## How to migrate from old dashboard (v1)
+## How to migrate from old dashboard (v1)
The new dashboard comes with a new docker image `netbirdio/dashboard:main`.
To migrate from the old dashboard (v1) `wiretrustee/dashboard:main` to the new one, please follow the steps below.
1. Stop the dashboard container `docker compose down dashboard`
2. Replace the docker image name in your `docker-compose.yml` with `netbirdio/dashboard:main`
-3. Recreate the dashboard container `docker compose up -d --force-recreate dashboard`
\ No newline at end of file
+3. Recreate the dashboard container `docker compose up -d --force-recreate dashboard`
From ba66201c642bb6a150379928d0f47dcd1c51a332 Mon Sep 17 00:00:00 2001
From: Aaron Dewes
Date: Thu, 12 Feb 2026 11:21:08 +0100
Subject: [PATCH 2/4] Remove architecture info tooltip for MacOS (#550)
* Remove architecture info tooltip for MacOS
Previously, this tooltip helped users determine which binary to download. Since #501, there is only one universal binary download link, so keeping the tooltip explaining how to determine the CPU architecture is unnecessary.
* fix: Remove unused imports
---
src/modules/setup-netbird-modal/MacOSTab.tsx | 29 --------------------
1 file changed, 29 deletions(-)
diff --git a/src/modules/setup-netbird-modal/MacOSTab.tsx b/src/modules/setup-netbird-modal/MacOSTab.tsx
index 27bc9f1e..f6584c05 100644
--- a/src/modules/setup-netbird-modal/MacOSTab.tsx
+++ b/src/modules/setup-netbird-modal/MacOSTab.tsx
@@ -6,17 +6,14 @@ import {
} from "@components/Accordion";
import Button from "@components/Button";
import Code from "@components/Code";
-import InlineLink from "@components/InlineLink";
import Separator from "@components/Separator";
import Steps from "@components/Steps";
import TabsContentPadding, { TabsContent } from "@components/Tabs";
-import { Tooltip, TooltipContent, TooltipTrigger } from "@components/Tooltip";
import { getNetBirdUpCommand, GRPC_API_ORIGIN } from "@utils/netbird";
import {
BeerIcon,
DownloadIcon,
ExternalLinkIcon,
- HelpCircle,
PackageOpenIcon,
TerminalSquareIcon,
} from "lucide-react";
@@ -50,32 +47,6 @@ export default function MacOSTab({
Download and run macOS Installer
-
-
-
-
-
-
- {`If you don't know what chip your Mac has, you can find out
- by clicking on the Apple logo in the top left corner of your
- screen and selecting 'About This Mac'.`}
-
-
-
- Learn more
-
-
-
-
-
Date: Thu, 12 Feb 2026 15:16:34 +0100
Subject: [PATCH 3/4] Indicate that local user auth is disabled (#551)
---
.../users/table-cells/UserStatusCell.tsx | 90 ++++++++++++-------
1 file changed, 59 insertions(+), 31 deletions(-)
diff --git a/src/modules/users/table-cells/UserStatusCell.tsx b/src/modules/users/table-cells/UserStatusCell.tsx
index a6a3824d..5d844357 100644
--- a/src/modules/users/table-cells/UserStatusCell.tsx
+++ b/src/modules/users/table-cells/UserStatusCell.tsx
@@ -4,16 +4,24 @@ import { cn } from "@utils/helpers";
import { ExternalLinkIcon, HelpCircle } from "lucide-react";
import React from "react";
import { User } from "@/interfaces/User";
+import { useAccount } from "@/modules/account/useAccount";
type Props = {
user: User;
};
export default function UserStatusCell({ user }: Readonly) {
+ const account = useAccount();
const status = user.status;
const isPendingApproval = user.pending_approval;
+ const isLocalAuthDisabled =
+ account?.settings?.local_auth_disabled === true &&
+ user.idp_id === "local";
const getStatusDisplay = () => {
+ if (isLocalAuthDisabled) {
+ return { text: "Disabled", color: "bg-gray-400" };
+ }
if (isPendingApproval) {
return { text: "Pending Approval", color: "bg-netbird" };
}
@@ -29,43 +37,63 @@ export default function UserStatusCell({ user }: Readonly) {
return { text: status || "Unknown", color: "bg-gray-400" };
};
+ const tooltipContent = isLocalAuthDisabled ? (
+
+
+ Local authentication is disabled. This user can no longer log in.
+ Use your IdP for authentication.
+
+
+
+ Learn more
+
+
+
+ ) : (
+
+
+ This user needs to be approved by an administrator before it can
+ join your organization.
+
+
+
+ If you want to disable approval for new users, go to{" "}
+
+ Settings
+ {" "}
+ and disable{" "}
+
+ {"'User Approval Required'"}
+
+ .
+
diff --git a/src/app/(dashboard)/reverse-proxy/custom-domains/layout.tsx b/src/app/(dashboard)/reverse-proxy/custom-domains/layout.tsx
new file mode 100644
index 00000000..70529903
--- /dev/null
+++ b/src/app/(dashboard)/reverse-proxy/custom-domains/layout.tsx
@@ -0,0 +1,8 @@
+import { globalMetaTitle } from "@utils/meta";
+import type { Metadata } from "next";
+import BlankLayout from "@/layouts/BlankLayout";
+
+export const metadata: Metadata = {
+ title: `Custom Domains - Reverse Proxy - ${globalMetaTitle}`,
+};
+export default BlankLayout;
diff --git a/src/app/(dashboard)/reverse-proxy/custom-domains/page.tsx b/src/app/(dashboard)/reverse-proxy/custom-domains/page.tsx
new file mode 100644
index 00000000..d052c0ce
--- /dev/null
+++ b/src/app/(dashboard)/reverse-proxy/custom-domains/page.tsx
@@ -0,0 +1,70 @@
+"use client";
+
+import Breadcrumbs from "@components/Breadcrumbs";
+import InlineLink from "@components/InlineLink";
+import Paragraph from "@components/Paragraph";
+import SkeletonTable from "@components/skeletons/SkeletonTable";
+import { RestrictedAccess } from "@components/ui/RestrictedAccess";
+import { usePortalElement } from "@hooks/usePortalElement";
+import { ExternalLinkIcon } from "lucide-react";
+import React, { lazy, Suspense } from "react";
+import ReverseProxyIcon from "@/assets/icons/ReverseProxyIcon";
+import { usePermissions } from "@/contexts/PermissionsProvider";
+import ReverseProxiesProvider from "@/contexts/ReverseProxiesProvider";
+import { REVERSE_PROXY_CUSTOM_DOMAINS_DOCS_LINK } from "@/interfaces/ReverseProxy";
+import PageContainer from "@/layouts/PageContainer";
+
+const CustomDomainsTable = lazy(
+ () => import("@/modules/reverse-proxy/domain/CustomDomainsTable"),
+);
+
+export default function ReverseProxyCustomDomainsPage() {
+ const { permission } = usePermissions();
+
+ const { ref: headingRef, portalTarget } =
+ usePortalElement();
+
+ return (
+
+
+
+ }
+ />
+
+
+
Domains
+
+ Add and manage custom domains for your reverse proxy services.
+
+
+ Learn more about
+
+ Custom Domains
+
+
+ in our documentation.
+
+
+
+
+ }>
+
+
+
+
+
+ );
+}
diff --git a/src/app/(dashboard)/reverse-proxy/page.tsx b/src/app/(dashboard)/reverse-proxy/page.tsx
new file mode 100644
index 00000000..8f5c4973
--- /dev/null
+++ b/src/app/(dashboard)/reverse-proxy/page.tsx
@@ -0,0 +1,15 @@
+"use client";
+
+import FullScreenLoading from "@components/ui/FullScreenLoading";
+import { useRouter } from "next/navigation";
+import { useEffect } from "react";
+
+export default function ReverseProxyRedirectPage() {
+ const router = useRouter();
+
+ useEffect(() => {
+ router.replace("/reverse-proxy/services");
+ }, [router]);
+
+ return ;
+}
diff --git a/src/app/(dashboard)/reverse-proxy/services/layout.tsx b/src/app/(dashboard)/reverse-proxy/services/layout.tsx
new file mode 100644
index 00000000..b895c6b6
--- /dev/null
+++ b/src/app/(dashboard)/reverse-proxy/services/layout.tsx
@@ -0,0 +1,8 @@
+import { globalMetaTitle } from "@utils/meta";
+import type { Metadata } from "next";
+import BlankLayout from "@/layouts/BlankLayout";
+
+export const metadata: Metadata = {
+ title: `Services - Reverse Proxy - ${globalMetaTitle}`,
+};
+export default BlankLayout;
diff --git a/src/app/(dashboard)/reverse-proxy/services/page.tsx b/src/app/(dashboard)/reverse-proxy/services/page.tsx
new file mode 100644
index 00000000..24238b49
--- /dev/null
+++ b/src/app/(dashboard)/reverse-proxy/services/page.tsx
@@ -0,0 +1,83 @@
+"use client";
+
+import Breadcrumbs from "@components/Breadcrumbs";
+import InlineLink from "@components/InlineLink";
+import Paragraph from "@components/Paragraph";
+import SkeletonTable from "@components/skeletons/SkeletonTable";
+import { RestrictedAccess } from "@components/ui/RestrictedAccess";
+import { usePortalElement } from "@hooks/usePortalElement";
+import { ExternalLinkIcon } from "lucide-react";
+import React, { lazy, Suspense } from "react";
+import ReverseProxyIcon from "@/assets/icons/ReverseProxyIcon";
+import { usePermissions } from "@/contexts/PermissionsProvider";
+import ReverseProxiesProvider from "@/contexts/ReverseProxiesProvider";
+import { REVERSE_PROXY_DOCS_LINK } from "@/interfaces/ReverseProxy";
+import PageContainer from "@/layouts/PageContainer";
+import { Callout } from "@components/Callout";
+import { isNetBirdHosted } from "@utils/netbird";
+
+const ReverseProxyTable = lazy(
+ () => import("@/modules/reverse-proxy/table/ReverseProxyTable"),
+);
+
+export default function ReverseProxyServicesPage() {
+ const { permission } = usePermissions();
+
+ const { ref: headingRef, portalTarget } =
+ usePortalElement();
+
+ return (
+
+
+
+ }
+ />
+
+
+
Services
+
+ Expose services securely through NetBird's reverse proxy.
+
+
+ Learn more about
+
+ Services
+
+
+ in our documentation.
+
+
+ {isNetBirdHosted() ? (
+
+ NetBird's Reverse Proxy is currently in beta and available at
+ no cost during this period. Features, functionality, and pricing are
+ subject to change upon release.
+
+ ) : (
+
+ NetBird's Reverse Proxy is currently in beta. Features
+ and functionality are subject to change upon release.
+
+ )}
+