Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@
"@types/chroma-js": "^3.1.1",
"@types/js-cookie": "^3.0.6",
"eslint-config-next": "^14.2.28",
"cypress": "^13.13.0",
"postcss": "^8",
"prettier": "3.0.3",
"tailwindcss": "^3"
Expand Down
4 changes: 2 additions & 2 deletions src/modules/peer/PeerSSHInstructions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const PeerSSHInstructions = ({
icon={<TerminalSquare size={16} className={"text-netbird"} />}
title={"Enable SSH Access"}
description={
"Allow remote SSH access to this machine from other connected network participants. NetBird's embedded SSH server is running on port 44338."
"Allow remote SSH access to this machine from other connected network participants."
}
color={"netbird"}
/>
Expand All @@ -56,7 +56,7 @@ export const PeerSSHInstructions = ({
<Code.Line>{`netbird down # if NetBird is already running`}</Code.Line>
</Code>
<Code>
<Code.Line>{`netbird up --allow-server-ssh`}</Code.Line>
<Code.Line>{`netbird up --allow-server-ssh --enable-ssh-root`}</Code.Line>
Comment thread
heisbrot marked this conversation as resolved.
</Code>
</Steps.Step>

Expand Down
7 changes: 4 additions & 3 deletions src/modules/peers/PeerVersionCell.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import FullTooltip from "@components/FullTooltip";
import InlineLink from "@components/InlineLink";
import {
Tooltip,
Expand All @@ -8,13 +7,14 @@ import {
} from "@components/Tooltip";
import MemoizedNetBirdIcon from "@components/ui/MemoizedNetBirdIcon";
import { getOperatingSystem } from "@hooks/useOperatingSystem";
import { parseVersionString } from "@utils/version";
import { compareVersions } from "@utils/version";
import { ArrowRightIcon, ArrowUpCircleIcon } from "lucide-react";
import * as React from "react";
import { useMemo } from "react";
import { useApplicationContext } from "@/contexts/ApplicationProvider";
import { OperatingSystem } from "@/interfaces/OperatingSystem";
import { PeerOperatingSystemIcon } from "@/modules/peers/PeerOperatingSystemIcon";
import FullTooltip from "@components/FullTooltip";

type Props = {
version: string;
Expand All @@ -31,7 +31,8 @@ export default function PeerVersionCell({ version, os, serial }: Props) {
operatingSystem === OperatingSystem.ANDROID
)
return false;
return parseVersionString(version) < parseVersionString(latestVersion);
if (!latestVersion) return false;
return !compareVersions(version, latestVersion);
}, [os, version, latestVersion]);

const updateIcon = useMemo(() => {
Expand Down
8 changes: 7 additions & 1 deletion src/modules/remote-access/ssh/useSSH.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,16 @@ export const useSSH = (client: any) => {
setConfig(config);

try {
const requiresJwt = await client.detectSSHServerType(
config.hostname,
config.port,
);

const ssh = await client.createSSHConnection(
config.hostname,
config.port,
config.username,
requiresJwt ? accessToken : undefined,
);

ssh.onclose = () => {
Expand All @@ -65,7 +71,7 @@ export const useSSH = (client: any) => {
return SSHStatus.DISCONNECTED;
}
},
[client, status],
[client, status, accessToken],
);

const disconnect = useCallback(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const loadConfig = (): Config => {
googleAnalyticsID: configJson?.googleAnalyticsID || undefined,
googleTagManagerID: configJson?.googleTagManagerID || undefined,
wasmPath:
configJson.wasmPath || "https://pkgs.netbird.io/wasm/client/v0.59.11",
configJson?.wasmPath || "https://pkgs.netbird.io/wasm/client/v0.60.0",
Comment thread
heisbrot marked this conversation as resolved.
} as Config;
};

Expand Down
34 changes: 34 additions & 0 deletions src/utils/version.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { isNativeSSHSupported } from "./version.js";

console.log("=== Testing isNativeSSHSupported ===");
const sshTestCases = [
{ version: "v0.59.9", shouldSupport: false },
{ version: "v0.59.10", shouldSupport: false },
{ version: "v0.59.11", shouldSupport: false },
{ version: "v0.60.0", shouldSupport: true },
{ version: "v0.60.1", shouldSupport: true },
{ version: "v0.61.0", shouldSupport: true },
{ version: "v1.0.0", shouldSupport: true },

// Edge cases
{ version: "development", shouldSupport: true, desc: "development build" },
{ version: "0.60.0", shouldSupport: true, desc: "no v prefix" },
{ version: "0.59.11", shouldSupport: false, desc: "no v prefix" },
{ version: "v0.60.0-beta", shouldSupport: true, desc: "with suffix" },
{ version: "v0.60.0-rc1", shouldSupport: true, desc: "with rc suffix" },
{ version: "v0.59.9-beta", shouldSupport: false, desc: "old version with suffix" },
];

let failures = 0;
sshTestCases.forEach(({ version, shouldSupport, desc }) => {
const result = isNativeSSHSupported(version);
const status = result === shouldSupport ? "✓" : "✗";
if (result !== shouldSupport) failures++;
const label = desc ? `${version.padEnd(15)} (${desc})` : version.padEnd(15);
console.log(
`${status} ${label} → ${result.toString().padStart(5)} (expected: ${shouldSupport})`,
);
});

console.log(`\n${failures} test(s) failed`);
process.exit(failures > 0 ? 1 : 0);
36 changes: 28 additions & 8 deletions src/utils/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,30 @@ export const getLatestNetbirdRelease = async (
}
};

export const parseVersionString = (version: string | undefined) => {
if (!version) return -1;
return parseInt(version.replace(/\D/g, ""));
/**
* Compare semantic versions.
* Returns true if version >= minVersion.
*/
export const compareVersions = (
version: string,
minVersion: string,
): boolean => {
const parseVersion = (v: string): number[] => {
return v.replace(/^v/, "").split(".").map(Number);
};

const vParts = parseVersion(version);
const minParts = parseVersion(minVersion);

for (let i = 0; i < Math.max(vParts.length, minParts.length); i++) {
const vPart = vParts[i] || 0;
const minPart = minParts[i] || 0;

if (vPart > minPart) return true;
if (vPart < minPart) return false;
}

return true;
};

/**
Expand All @@ -51,16 +72,15 @@ export const isRoutingPeerSupported = (version: string, os: string) => {
const operatingSystem = getOperatingSystem(os);
if (operatingSystem == OperatingSystem.LINUX) return true;
if (version == "development") return true;
const versionNumber = parseVersionString(version);
return versionNumber >= 366;
return compareVersions(version, "0.36.6");
};

/**
* Check if native SSH is supported
* Check if native SSH is supported.
* Supported starting from NetBird v0.60.0+.
* @param version
*/
export const isNativeSSHSupported = (version: string) => {
if (version == "development") return true;
const versionNumber = parseVersionString(version);
return versionNumber >= 999999;
return compareVersions(version, "0.60.0");
};