Skip to content
Closed
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
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<img src="https://img.shields.io/github/forks/Termix-SSH/Termix?style=flat&label=Forks&color=F39044&labelColor=1a1a1a" />
<img src="https://img.shields.io/github/v/release/Termix-SSH/Termix?style=flat&label=Release&color=F39044&labelColor=1a1a1a&v=1" />
<a href="https://discord.gg/jVQGdvHDrf"><img alt="Discord" src="https://img.shields.io/discord/1347374268253470720?color=F39044&labelColor=1a1a1a" /></a>
<a href="https://donate.termix.site/"><img alt="Donate" src="https://img.shields.io/badge/Donate-Support%20Termix-F39044?style=flat&labelColor=1a1a1a" /></a>
</p>

<br />
Expand Down Expand Up @@ -263,6 +264,14 @@ networks:

<br />

## Donate

Termix is free and open source with no subscriptions or paid plans. If you find it useful, consider donating to help cover server costs, domains, and development time.

[Donate](https://donate.termix.site/)

<br />

## Screenshots

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-AR.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## التبرع

Termix مجاني ومفتوح المصدر بدون اشتراكات أو خطط مدفوعة. إذا وجدته مفيدًا، فكّر في التبرع للمساعدة في تغطية تكاليف الخادم والنطاقات ووقت التطوير.

[تبرع](https://donate.termix.site/)

<br />

## لقطات الشاشة

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## 捐赠

Termix 是免费且开源的,没有订阅或付费计划。如果您觉得它有用,请考虑捐赠以帮助支付服务器费用、域名费用和开发时间。

[捐赠](https://donate.termix.site/)

<br />

## 展示

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-DE.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## Spenden

Termix ist kostenlos und Open Source ohne Abonnements oder kostenpflichtige Pläne. Wenn Sie es nützlich finden, erwägen Sie eine Spende, um Serverkosten, Domains und Entwicklungszeit zu decken.

[Spenden](https://donate.termix.site/)

<br />

## Screenshots

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-ES.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## Donar

Termix es gratuito y de código abierto sin suscripciones ni planes de pago. Si lo encuentras útil, considera hacer una donación para ayudar a cubrir los costos del servidor, dominios y tiempo de desarrollo.

[Donar](https://donate.termix.site/)

<br />

## Capturas de Pantalla

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-FR.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## Faire un don

Termix est gratuit et open source sans abonnements ni plans payants. Si vous le trouvez utile, pensez à faire un don pour aider à couvrir les coûts de serveur, les noms de domaine et le temps de développement.

[Faire un don](https://donate.termix.site/)

<br />

## Captures d'ecran

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-HI.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## दान करें

Termix मुफ़्त और ओपन सोर्स है, इसमें कोई सदस्यता या भुगतान योजना नहीं है। यदि आपको यह उपयोगी लगता है, तो सर्वर लागत, डोमेन और विकास समय को कवर करने में मदद के लिए दान करने पर विचार करें।

[दान करें](https://donate.termix.site/)

<br />

## स्क्रीनशॉट

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-IT.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## Dona

Termix è gratuito e open source senza abbonamenti o piani a pagamento. Se lo trovi utile, considera di fare una donazione per aiutare a coprire i costi del server, i domini e il tempo di sviluppo.

[Dona](https://donate.termix.site/)

<br />

## Screenshot

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-JA.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## 寄付

Termix はサブスクリプションや有料プランのない、無料のオープンソースプロジェクトです。便利だと感じた場合は、サーバーコスト、ドメイン、開発時間をカバーするための寄付をご検討ください。

[寄付する](https://donate.termix.site/)

<br />

## スクリーンショット

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-KO.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## 후원

Termix는 구독이나 유료 플랜 없이 무료 오픈소스 프로젝트입니다. 유용하게 사용하고 있다면 서버 비용, 도메인, 개발 시간을 지원하기 위한 후원을 고려해 주세요.

[후원하기](https://donate.termix.site/)

<br />

## 스크린샷

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-PT.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## Doar

O Termix é gratuito e de código aberto, sem assinaturas ou planos pagos. Se o achar útil, considere fazer uma doação para ajudar a cobrir os custos de servidor, domínios e tempo de desenvolvimento.

[Doar](https://donate.termix.site/)

<br />

## Capturas de Tela

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-RU.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## Пожертвование

Termix — бесплатный проект с открытым исходным кодом без подписок и платных планов. Если вы находите его полезным, рассмотрите возможность пожертвования для покрытия расходов на серверы, домены и время разработки.

[Пожертвовать](https://donate.termix.site/)

<br />

## Скриншоты

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-TR.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## Bağış Yapın

Termix, abonelik veya ücretli plan olmayan ücretsiz ve açık kaynaklı bir projedir. Faydalı buluyorsanız, sunucu maliyetleri, alan adları ve geliştirme süresini karşılamaya yardımcı olmak için bağış yapmayı düşünebilirsiniz.

[Bağış Yap](https://donate.termix.site/)

<br />

## Ekran Goruntuleri

<div align="center">
Expand Down
8 changes: 8 additions & 0 deletions readme/README-VI.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ networks:

<br />

## Quyên góp

Termix là dự án miễn phí và mã nguồn mở, không có gói đăng ký hay trả phí. Nếu bạn thấy hữu ích, hãy cân nhắc quyên góp để giúp trang trải chi phí máy chủ, tên miền và thời gian phát triển.

[Quyên góp](https://donate.termix.site/)

<br />

## Anh Chup Man Hinh

<div align="center">
Expand Down
76 changes: 39 additions & 37 deletions src/backend/ssh/tunnel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -992,44 +992,46 @@ async function connectSSHTunnel(
});
}

if (
resolvedEndpointCredentials.authMethod === "password" &&
!resolvedEndpointCredentials.password
) {
const errorMessage = `Cannot connect tunnel '${tunnelName}': endpoint host requires password authentication but no plaintext password available. Enable autostart for endpoint host or configure credentials in tunnel connection.`;
tunnelLogger.error(errorMessage, undefined, {
operation: "tunnel_endpoint_password_unavailable",
tunnelName,
endpointHost: `${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP}:${tunnelConfig.endpointPort}`,
endpointAuthMethod: resolvedEndpointCredentials.authMethod,
});
broadcastTunnelStatus(tunnelName, {
connected: false,
status: CONNECTION_STATES.FAILED,
reason: errorMessage,
});
tunnelConnecting.delete(tunnelName);
return;
}
if (!isSingleHostTunnel(tunnelConfig)) {
if (
resolvedEndpointCredentials.authMethod === "password" &&
!resolvedEndpointCredentials.password
) {
const errorMessage = `Cannot connect tunnel '${tunnelName}': endpoint host requires password authentication but no plaintext password available. Enable autostart for endpoint host or configure credentials in tunnel connection.`;
tunnelLogger.error(errorMessage, undefined, {
operation: "tunnel_endpoint_password_unavailable",
tunnelName,
endpointHost: `${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP}:${tunnelConfig.endpointPort}`,
endpointAuthMethod: resolvedEndpointCredentials.authMethod,
});
broadcastTunnelStatus(tunnelName, {
connected: false,
status: CONNECTION_STATES.FAILED,
reason: errorMessage,
});
tunnelConnecting.delete(tunnelName);
return;
}

if (
resolvedEndpointCredentials.authMethod === "key" &&
!resolvedEndpointCredentials.sshKey
) {
const errorMessage = `Cannot connect tunnel '${tunnelName}': endpoint host requires key authentication but no plaintext key available. Enable autostart for endpoint host or configure credentials in tunnel connection.`;
tunnelLogger.error(errorMessage, undefined, {
operation: "tunnel_endpoint_key_unavailable",
tunnelName,
endpointHost: `${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP}:${tunnelConfig.endpointPort}`,
endpointAuthMethod: resolvedEndpointCredentials.authMethod,
});
broadcastTunnelStatus(tunnelName, {
connected: false,
status: CONNECTION_STATES.FAILED,
reason: errorMessage,
});
tunnelConnecting.delete(tunnelName);
return;
if (
resolvedEndpointCredentials.authMethod === "key" &&
!resolvedEndpointCredentials.sshKey
) {
const errorMessage = `Cannot connect tunnel '${tunnelName}': endpoint host requires key authentication but no plaintext key available. Enable autostart for endpoint host or configure credentials in tunnel connection.`;
tunnelLogger.error(errorMessage, undefined, {
operation: "tunnel_endpoint_key_unavailable",
tunnelName,
endpointHost: `${tunnelConfig.endpointUsername}@${tunnelConfig.endpointIP}:${tunnelConfig.endpointPort}`,
endpointAuthMethod: resolvedEndpointCredentials.authMethod,
});
broadcastTunnelStatus(tunnelName, {
connected: false,
status: CONNECTION_STATES.FAILED,
reason: errorMessage,
});
tunnelConnecting.delete(tunnelName);
return;
}
}

const conn = new Client();
Expand Down
8 changes: 7 additions & 1 deletion src/ui/AppShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { AdminSettingsPanel } from "@/sidebar/AdminSettingsPanel";
import { CredentialsPanel } from "@/sidebar/CredentialsPanel";
import { SplitView } from "@/shell/SplitView";
import { renderTabContent } from "@/shell/tabUtils";
import { AlertManager } from "@/dashboard/panels/alerts/AlertManager";
import { TabBar } from "@/shell/TabBar";
import type {
Tab,
Expand Down Expand Up @@ -207,6 +208,7 @@ export function AppShell({
const [hostsLoading, setHostsLoading] = useState(true);
const [allHosts, setAllHosts] = useState<Host[]>([]);
const [isAdmin, setIsAdmin] = useState(false);
const [userId, setUserId] = useState<string | null>(null);
const [backgroundTabRecords, setBackgroundTabRecords] = useState<
OpenTabRecord[]
>([]);
Expand Down Expand Up @@ -246,7 +248,10 @@ export function AppShell({

useEffect(() => {
getUserInfo()
.then((info) => setIsAdmin(info.is_admin))
.then((info) => {
setIsAdmin(info.is_admin);
setUserId(info.userId);
})
.catch(() => setIsAdmin(false));
}, []);

Expand Down Expand Up @@ -1702,6 +1707,7 @@ export function AppShell({
}}
/>
<TransferMonitor />
<AlertManager userId={userId} loggedIn={!!username} />
</>
);
}
28 changes: 28 additions & 0 deletions src/ui/dashboard/DashboardTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,20 @@ export function DashboardTab({
{t("dashboard.docs")}
</a>
</Button>
<Button
variant="ghost"
size="sm"
className="text-xs text-muted-foreground hover:text-foreground"
asChild
>
<a
href="https://donate.termix.site/"
target="_blank"
rel="noreferrer"
>
{t("dashboard.donate")}
</a>
</Button>
</div>
</Card>
{allSlots.map((slot) => (
Expand Down Expand Up @@ -1729,6 +1743,20 @@ export function DashboardTab({
{t("dashboard.docs")}
</a>
</Button>
<Button
variant="ghost"
size="sm"
className="text-xs text-muted-foreground hover:text-foreground"
asChild
>
<a
href="https://donate.termix.site/"
target="_blank"
rel="noreferrer"
>
{t("dashboard.donate")}
</a>
</Button>
<Separator orientation="vertical" className="mx-1 h-5" />
{editMode ? (
<>
Expand Down
Loading