diff --git a/README.md b/README.md index ab857350e..1827f2570 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@
-Pangolin is an open-source, identity-based remote access platform built on WireGuard® that enables secure, seamless connectivity to private and public resources. Pangolin combines reverse proxy and VPN capabilities into one platform, providing browser-based access to web applications and client-based access to any private resources with NAT traversal, all with granular access controls. +Pangolin is an open-source, identity-based remote access platform built on WireGuard® that enables secure connectivity to infrastructure anywhere. It combines reverse-proxy and VPN capabilities into one platform, providing browser-based access to web applications and client-based access to private resources with NAT traversal, all with granular access control. ## Installation @@ -63,11 +63,26 @@ Pangolin is an open-source, identity-based remote access platform built on WireG Pangolin's site connectors provide gateways into networks so you can access any networked resources. Sites use outbound tunnels and intelligent NAT traversal to make networks behind restrictive firewalls available for authorized access without public IPs or open ports. Easily deploy a site as a binary or container on any platform. +* Lightweight user-space connector runs anywhere +* Punches through any firewall +* Doesn't require open ports or a public IP +* Strict network segmentation +* WireGuard-based +* Get alerts when a device or network resource goes down +
### Browser-based reverse proxy access
-Expose web applications through identity and context-aware tunneled reverse proxies. Users access applications through any web browser with authentication and granular access control without installing a client. Pangolin handles routing, load balancing, health checking, and automatic SSL certificates without exposing your network directly to the internet.
+Expose HTTPS web applications and connect to VNC, RDP, and SSH entirely in the browser through identity and context-aware tunneled reverse proxies. Users access resources with authentication and granular access control without installing a client. Pangolin handles routing, load balancing, health checking, and automatic SSL certificates without exposing your network directly to the internet.
+
+* Expose a web panel anywhere
+* Access via any web browser
+* Single sign-on across all resources
+* HTTPS resources
+* Remote desktop in the browser with VNC and RDP
+* In-browser SSH terminal with privileged access management (PAM)
+* PIN codes, passcodes, email OTP, geoblocking, allow-lists, and more
@@ -75,14 +90,35 @@ Expose web applications through identity and context-aware tunneled reverse prox
Access private resources like SSH servers, databases, RDP, and entire network ranges through Pangolin clients. Intelligent NAT traversal enables connections even through restrictive firewalls, while DNS aliases provide friendly names and fast connections to resources across all your sites. Add redundancy by routing traffic through multiple connectors in your network.
+* Peer-to-peer with intelligent NAT traversal
+* Hosts/IPs and port ranges
+* Network ranges/CIDRs
+* Friendly DNS aliases for network addresses
+* Privileged access management (PAM) with SSH resources
+* Private HTTPS resources only accessible on the private network
+
### Give users and roles access to resources
-Use Pangolin's built in users or bring your own identity provider and set up role based access control (RBAC). Grant users access to specific resources, not entire networks. Unlike traditional VPNs that expose full network access, Pangolin's zero-trust model ensures users can only reach the applications, services, and routes you explicitly define.
+Use Pangolin's built-in users or bring your own identity provider and set up role-based access control (RBAC). Grant users access to specific resources, not entire networks. Unlike traditional VPNs that expose full network access, Pangolin's zero-trust model ensures users can only reach the applications, services, and routes you explicitly define.
+
+* Bring your existing identity provider (IdP) or use Pangolin identities
+* Sync users and roles from your IdP
+* User- and role-based access control
+* Full network audit and access logs
+### Find and launch resources from a personalized home page
+
+Give users a landing page to quickly find and open the resources they can access. Resources are grouped by site or label, searchable, and filterable, with grid or list views. Saved views capture filters, grouping, and layout as personal or organization-wide defaults.
+
+* Single place for admins and non-admins to see accessible resources
+* Create reusable views for common access patterns
+
+
+
## Download Clients
Download the Pangolin client for your platform:
diff --git a/install/main.go b/install/main.go
index 001f09a52..13afbaca3 100644
--- a/install/main.go
+++ b/install/main.go
@@ -76,7 +76,7 @@ var redisFlag *bool
func main() {
crowdsecFlag := flag.Bool("crowdsec", false, "Enable the CrowdSec installation prompt")
- redisFlag = flag.Bool("redis", false, "Install Redis as cacheing solution. Required for HA. Not required for the Enterprise version.")
+ redisFlag = flag.Bool("redis", false, "Install Redis as caching solution. Required for HA. Not required for the Enterprise version.")
flag.Parse()
// print a banner about prerequisites - opening port 80, 443, 51820, and 21820 on the VPS and firewall and pointing your domain to the VPS IP with a records. Docs are at http://localhost:3000/Getting%20Started/dns-networking
diff --git a/messages/bg-BG.json b/messages/bg-BG.json
index 2d455afa8..4bf0d9ab6 100644
--- a/messages/bg-BG.json
+++ b/messages/bg-BG.json
@@ -449,8 +449,14 @@
"provisioningManage": "Осигуряване",
"provisioningDescription": "Управление на ключовете за осигуряване и преглед на чаканещите сайтове за одобрение.",
"pendingSites": "Чаканещи сайтове",
- "siteApproveSuccess": "Сайтът е одобрен успешно",
+ "siteApproveSuccess": "Сайтът и свързаните ресурси са одобрени успешно",
"siteApproveError": "Грешка при одобряването на сайта",
+ "siteReject": "Отказ на сайт",
+ "siteQuestionReject": "Сигурни ли сте, че искате да откажете този сайт?",
+ "siteMessageReject": "Това ще изтрие окончателно сайта и всички свързани ресурси, които все още са на изчакване.",
+ "siteConfirmReject": "Потвърдете отказ на сайт",
+ "siteRejectSuccess": "Сайтът беше успешно отхвърлен",
+ "siteRejectError": "Грешка при отхвърляне на сайта",
"provisioningKeys": "Ключове за осигуряване",
"searchProvisioningKeys": "Търсене на ключове за осигуряване...",
"provisioningKeysAdd": "Генериране на ключ за осигуряване",
@@ -466,8 +472,8 @@
"provisioningKeysSave": "Запазете ключа за осигуряване",
"provisioningKeysSaveDescription": "Ще можете да видите това само веднъж. Копирайте го на сигурно място.",
"provisioningKeysErrorCreate": "Грешка при създаване на ключ за осигуряване",
- "provisioningKeysList": "Нов ключ за осигуряване",
- "provisioningKeysMaxBatchSize": "Максимален размер на пакет",
+ "provisioningKeysList": "Нов ключ за разпределяне",
+ "provisioningKeysMaxBatchSize": "Максимален размер на пакета",
"provisioningKeysUnlimitedBatchSize": "Неограничен размер на партида (без лимит)",
"provisioningKeysMaxBatchUnlimited": "Неограничено",
"provisioningKeysMaxBatchSizeInvalid": "Въведете валиден максимален размер на партида (1–1,000,000).",
@@ -480,7 +486,7 @@
"provisioningKeysNeverUsed": "Никога",
"provisioningKeysEdit": "Редактиране на ключ за осигуряване",
"provisioningKeysEditDescription": "Актуализирайте максималния размер на партида и времето на изтичане за този ключ.",
- "provisioningKeysApproveNewSites": "Одобрете нови сайтове",
+ "provisioningKeysApproveNewSites": "Одобряване на нови сайтове",
"provisioningKeysApproveNewSitesDescription": "Автоматично одобряване на сайтове, които се регистрират с този ключ.",
"provisioningKeysUpdateError": "Грешка при актуализирането на ключа за осигуряване",
"provisioningKeysUpdated": "Ключът за осигуряване е актуализиран",
@@ -1397,6 +1403,7 @@
"createOrgUser": "Създаване на Организационна Потребител",
"actionUpdateOrg": "Актуализиране на организацията",
"actionRemoveInvitation": "Премахване на поканата.",
+ "actionRemoveUserRole": "Премахване на роля на потребител",
"actionUpdateUser": "Актуализиране на потребител",
"actionGetUser": "Получаване на потребител",
"actionGetOrgUser": "Вземете потребител на организация",
@@ -1419,6 +1426,8 @@
"setupTokenDescription": "Въведете конфигурационния токен от сървърната конзола.",
"setupTokenRequired": "Необходим е конфигурационен токен",
"actionUpdateSite": "Актуализиране на сайт",
+ "actionApproveSite": "Одобряване на сайт",
+ "actionRejectSite": "Отказ на сайт",
"actionResetSiteBandwidth": "Нулиране на честотната лента на организацията",
"actionListSiteRoles": "Изброяване на позволените роли за сайта",
"actionCreateResource": "Създаване на ресурс",
@@ -1502,6 +1511,10 @@
"actionListInvitations": "Списък с покани",
"actionExportLogs": "Експортиране на дневници",
"actionViewLogs": "Преглед на дневници",
+ "actionCreateSiteProvisioningKey": "Създаване на ключ за предоставяне на сайт",
+ "actionListSiteProvisioningKeys": "Списък на ключовете за предоставяне на сайт",
+ "actionUpdateSiteProvisioningKey": "Актуализиране на ключ за предоставяне на сайт",
+ "actionDeleteSiteProvisioningKey": "Изтриване на ключ за предоставяне на сайт",
"noneSelected": "Нищо не е избрано",
"orgNotFound2": "Няма намерени организации.",
"search": "Търси…",
@@ -1516,6 +1529,7 @@
"otpAuthDescription": "Въведете кода от приложението за удостоверяване или един от вашите резервни кодове за еднократна употреба.",
"otpAuthSubmit": "Изпрати код",
"idpContinue": "Или продължете със",
+ "idpLastUsed": "Последно използвано",
"otpAuthBack": "Назад към парола",
"navbar": "Навигационно меню",
"navbarDescription": "Главно навигационно меню за приложението",
@@ -3801,5 +3815,6 @@
"rdpUploadFailed": "Качването неуспешно",
"rdpUnicodeKeyboardMode": "Режим на unicode клавиатура",
"sessionToolbarShow": "Показване на лентата с инструменти",
- "sessionToolbarHide": "Скриване на лентата с инструменти"
+ "sessionToolbarHide": "Скриване на лентата с инструменти",
+ "actionUpdateSiteApprovals": "Обновяване на одобренията на сайта"
}
diff --git a/messages/cs-CZ.json b/messages/cs-CZ.json
index f456ee3b9..0d96a80cd 100644
--- a/messages/cs-CZ.json
+++ b/messages/cs-CZ.json
@@ -449,8 +449,14 @@
"provisioningManage": "Zajištění",
"provisioningDescription": "Spravovat klíče pro nastavení a zkontrolovat čekající stránky čekající na schválení.",
"pendingSites": "Nevyřízené weby",
- "siteApproveSuccess": "Web byl úspěšně schválen",
+ "siteApproveSuccess": "Stránka a přidružené zdroje byly úspěšně schváleny",
"siteApproveError": "Chyba při schvalování webu",
+ "siteReject": "Odmítnout stránku",
+ "siteQuestionReject": "Opravdu chcete tuto stránku odmítnout?",
+ "siteMessageReject": "Toto trvale odstraní stránku a všechny přidružené zdroje, které jsou stále nevyřízené.",
+ "siteConfirmReject": "Potvrdit odmítnutí stránky",
+ "siteRejectSuccess": "Stránka byla úspěšně odmítnuta",
+ "siteRejectError": "Chyba při odmítání stránky",
"provisioningKeys": "Poskytovací klíče",
"searchProvisioningKeys": "Hledat klíče k zajišťování...",
"provisioningKeysAdd": "Generovat zajišťovací klíč",
@@ -466,12 +472,12 @@
"provisioningKeysSave": "Uložit konfigurační klíč",
"provisioningKeysSaveDescription": "Toto můžete vidět pouze jednou. Zkopírujte ho na bezpečné místo.",
"provisioningKeysErrorCreate": "Chyba při vytváření doplňovacího klíče",
- "provisioningKeysList": "Nový klíč pro poskytování informací",
+ "provisioningKeysList": "Nový provisioning klíč",
"provisioningKeysMaxBatchSize": "Maximální velikost dávky",
"provisioningKeysUnlimitedBatchSize": "Neomezená velikost šarže (bez omezení)",
"provisioningKeysMaxBatchUnlimited": "Bez omezení",
"provisioningKeysMaxBatchSizeInvalid": "Zadejte platnou maximální velikost šarže (1–1,000,000).",
- "provisioningKeysValidUntil": "Platné do",
+ "provisioningKeysValidUntil": "Platná do",
"provisioningKeysValidUntilHint": "Ponechte prázdné, pokud vyprší platnost.",
"provisioningKeysValidUntilInvalid": "Zadejte platné datum a čas.",
"provisioningKeysNumUsed": "Časy použití",
@@ -1397,6 +1403,7 @@
"createOrgUser": "Vytvořit Org uživatele",
"actionUpdateOrg": "Aktualizovat organizaci",
"actionRemoveInvitation": "Odstranit pozvání",
+ "actionRemoveUserRole": "Odstranit uživatelskou roli",
"actionUpdateUser": "Aktualizovat uživatele",
"actionGetUser": "Získat uživatele",
"actionGetOrgUser": "Získat uživatele organizace",
@@ -1419,6 +1426,8 @@
"setupTokenDescription": "Zadejte nastavovací token z konzole serveru.",
"setupTokenRequired": "Je vyžadován token nastavení",
"actionUpdateSite": "Aktualizovat stránku",
+ "actionApproveSite": "Schválit stránku",
+ "actionRejectSite": "Odmítnout stránku",
"actionResetSiteBandwidth": "Resetovat šířku pásma organizace",
"actionListSiteRoles": "Seznam povolených rolí webu",
"actionCreateResource": "Vytvořit zdroj",
@@ -1502,6 +1511,10 @@
"actionListInvitations": "Seznam pozvánek",
"actionExportLogs": "Exportovat protokoly",
"actionViewLogs": "Zobrazit logy",
+ "actionCreateSiteProvisioningKey": "Vytvořit klíč pro zřízení webu",
+ "actionListSiteProvisioningKeys": "Seznam klíčů pro zřízení webu",
+ "actionUpdateSiteProvisioningKey": "Aktualizovat klíč pro zřízení webu",
+ "actionDeleteSiteProvisioningKey": "Smazat klíč pro zřízení webu",
"noneSelected": "Není vybráno",
"orgNotFound2": "Nebyly nalezeny žádné organizace.",
"search": "Vyhledávání…",
@@ -1516,6 +1529,7 @@
"otpAuthDescription": "Zadejte kód z vaší autentizační aplikace nebo jeden z vlastních záložních kódů.",
"otpAuthSubmit": "Odeslat kód",
"idpContinue": "Nebo pokračovat s",
+ "idpLastUsed": "Naposled použito",
"otpAuthBack": "Zpět na heslo",
"navbar": "Navigation Menu",
"navbarDescription": "Hlavní navigační menu aplikace",
@@ -3801,5 +3815,6 @@
"rdpUploadFailed": "Nahrání selhalo",
"rdpUnicodeKeyboardMode": "Režim Unicode klávesnice",
"sessionToolbarShow": "Zobrazit panel nástrojů",
- "sessionToolbarHide": "Skrýt panel nástrojů"
+ "sessionToolbarHide": "Skrýt panel nástrojů",
+ "actionUpdateSiteApprovals": "Aktualizovat schválení webu"
}
diff --git a/messages/da-DK.json b/messages/da-DK.json
index ce08bff23..f88ffa474 100644
--- a/messages/da-DK.json
+++ b/messages/da-DK.json
@@ -449,8 +449,14 @@
"provisioningManage": "Provisionering",
"provisioningDescription": "Administrer provisioneringsnøgler og gennemgå ventende sites som venter på godkendelse.",
"pendingSites": "Ventende sites",
- "siteApproveSuccess": "Med succes godkendelse af site",
+ "siteApproveSuccess": "Site og tilknyttede ressourcer godkendt med succes",
"siteApproveError": "Fejl ved godkendelse af side",
+ "siteReject": "Afvis Site",
+ "siteQuestionReject": "Er du sikker på, at du vil afvise dette site?",
+ "siteMessageReject": "Dette vil permanent slette sitet og enhver tilknyttet ressource, der stadig er i afventning.",
+ "siteConfirmReject": "Bekræft Afvis Site",
+ "siteRejectSuccess": "Site afvist med succes",
+ "siteRejectError": "Fejl ved afvisning af sitet",
"provisioningKeys": "Provisioneringsnøgler",
"searchProvisioningKeys": "Søg varer i provisioneringsnøgler...",
"provisioningKeysAdd": "Generer provisioneringsnøgle",
@@ -467,7 +473,7 @@
"provisioningKeysSaveDescription": "Du kan kun se denne én gang. Kopiér det til et sikkert sted.",
"provisioningKeysErrorCreate": "Fejl under oprettelse af provisioneringsnøgle",
"provisioningKeysList": "Ny provisioneringsnøgle",
- "provisioningKeysMaxBatchSize": "Maks størrelse på bunt",
+ "provisioningKeysMaxBatchSize": "Maksimum Batch Størrelse",
"provisioningKeysUnlimitedBatchSize": "Ubegrænset mengde bunt (ingen begrænsning)",
"provisioningKeysMaxBatchUnlimited": "Ubegrænset",
"provisioningKeysMaxBatchSizeInvalid": "Angiv en gyldig sjakkstørrelse (1–1 000.000).",
@@ -1397,6 +1403,7 @@
"createOrgUser": "Opret organisationsbruger",
"actionUpdateOrg": "Opdater organisation",
"actionRemoveInvitation": "Fjern invitation",
+ "actionRemoveUserRole": "Fjern Brugers Rolle",
"actionUpdateUser": "Opdater bruger",
"actionGetUser": "Hent bruger",
"actionGetOrgUser": "Hent organisationsbruger",
@@ -1419,6 +1426,8 @@
"setupTokenDescription": "Indtast opsætningstoken fra serverkonsollen.",
"setupTokenRequired": "Opsætningstoken er nødvendig",
"actionUpdateSite": "Opdater site",
+ "actionApproveSite": "Godkend Site",
+ "actionRejectSite": "Afvis Site",
"actionResetSiteBandwidth": "Nulstil organisationsbåndbredde",
"actionListSiteRoles": "Vis tilladte områderoller",
"actionCreateResource": "Opret ressource",
@@ -1502,6 +1511,10 @@
"actionListInvitations": "Vis invitationer",
"actionExportLogs": "Eksportér logs",
"actionViewLogs": "Vis logs",
+ "actionCreateSiteProvisioningKey": "Opret provisioneringsnøgle til site",
+ "actionListSiteProvisioningKeys": "Vis provisioneringsnøgler til site",
+ "actionUpdateSiteProvisioningKey": "Opdater provisioneringsnøgle til site",
+ "actionDeleteSiteProvisioningKey": "Slet provisioneringsnøgle til site",
"noneSelected": "Ingen valgt",
"orgNotFound2": "Ingen organisationer fundet.",
"search": "Søg…",
@@ -1516,6 +1529,7 @@
"otpAuthDescription": "Indtast koden fra autentiseringsappen din eller en af dine engangs reservekoder.",
"otpAuthSubmit": "Send kode",
"idpContinue": "Eller fortsæt med",
+ "idpLastUsed": "Sidst brugt",
"otpAuthBack": "Tilbage til adgangskode",
"navbar": "Navigationsmenu",
"navbarDescription": "Hovednavigasjonsmeny for applikationen",
@@ -3801,5 +3815,6 @@
"rdpUploadFailed": "Uploaden mislykkedes",
"rdpUnicodeKeyboardMode": "Unicode tastaturtilstand",
"sessionToolbarShow": "Vis værktøjslinje",
- "sessionToolbarHide": "Skjul værktøjslinje"
+ "sessionToolbarHide": "Skjul værktøjslinje",
+ "actionUpdateSiteApprovals": "Opdater godkendelser på site"
}
diff --git a/messages/de-DE.json b/messages/de-DE.json
index dc7dbb808..615759bf1 100644
--- a/messages/de-DE.json
+++ b/messages/de-DE.json
@@ -449,8 +449,14 @@
"provisioningManage": "Bereitstellung",
"provisioningDescription": "Bereitstellungsschlüssel verwalten und ausstehende Standorte prüfen, die noch auf Genehmigung warten.",
"pendingSites": "Ausstehende Standorte",
- "siteApproveSuccess": "Standort erfolgreich freigegeben",
+ "siteApproveSuccess": "Site und zugehörige Ressourcen erfolgreich genehmigt",
"siteApproveError": "Fehler beim Genehmigen des Standorts",
+ "siteReject": "Site ablehnen",
+ "siteQuestionReject": "Sind Sie sicher, dass Sie diese Site ablehnen möchten?",
+ "siteMessageReject": "Dies wird die Site und alle damit verbundenen, noch ausstehenden Ressourcen dauerhaft löschen.",
+ "siteConfirmReject": "Ablehnung der Site bestätigen",
+ "siteRejectSuccess": "Site erfolgreich abgelehnt",
+ "siteRejectError": "Fehler beim Ablehnen der Site",
"provisioningKeys": "Bereitstellungsschlüssel",
"searchProvisioningKeys": "Bereitstellungsschlüssel suchen...",
"provisioningKeysAdd": "Bereitstellungsschlüssel generieren",
@@ -467,7 +473,7 @@
"provisioningKeysSaveDescription": "Sie können dies nur einmal sehen. Kopieren Sie es an einen sicheren Ort.",
"provisioningKeysErrorCreate": "Fehler beim Erstellen des Bereitstellungsschlüssels",
"provisioningKeysList": "Neuer Bereitstellungsschlüssel",
- "provisioningKeysMaxBatchSize": "Max. Batch-Größe",
+ "provisioningKeysMaxBatchSize": "Maximale Batch-Größe",
"provisioningKeysUnlimitedBatchSize": "Unbegrenzte Batch-Größe (kein Limit)",
"provisioningKeysMaxBatchUnlimited": "Unbegrenzt",
"provisioningKeysMaxBatchSizeInvalid": "Geben Sie eine gültige maximale Batchgröße ein (1–1.000.000).",
@@ -480,7 +486,7 @@
"provisioningKeysNeverUsed": "Nie",
"provisioningKeysEdit": "Bereitstellungsschlüssel bearbeiten",
"provisioningKeysEditDescription": "Aktualisieren Sie die maximale Batch-Größe und Ablaufzeit für diesen Schlüssel.",
- "provisioningKeysApproveNewSites": "Neuen Standort genehmigen",
+ "provisioningKeysApproveNewSites": "Neue Sites genehmigen",
"provisioningKeysApproveNewSitesDescription": "Sites, die sich mit diesem Schlüssel registrieren, automatisch freigeben.",
"provisioningKeysUpdateError": "Fehler beim Aktualisieren des Bereitstellungsschlüssels",
"provisioningKeysUpdated": "Bereitstellungsschlüssel aktualisiert",
@@ -1397,6 +1403,7 @@
"createOrgUser": "Org Benutzer erstellen",
"actionUpdateOrg": "Organisation aktualisieren",
"actionRemoveInvitation": "Einladung entfernen",
+ "actionRemoveUserRole": "Benutzerrolle entfernen",
"actionUpdateUser": "Benutzer aktualisieren",
"actionGetUser": "Benutzer abrufen",
"actionGetOrgUser": "Organisationsbenutzer abrufen",
@@ -1419,6 +1426,8 @@
"setupTokenDescription": "Geben Sie das Setup-Token von der Serverkonsole ein.",
"setupTokenRequired": "Setup-Token ist erforderlich",
"actionUpdateSite": "Standorte aktualisieren",
+ "actionApproveSite": "Site genehmigen",
+ "actionRejectSite": "Site ablehnen",
"actionResetSiteBandwidth": "Organisations-Bandbreite zurücksetzen",
"actionListSiteRoles": "Erlaubte Standort-Rollen auflisten",
"actionCreateResource": "Ressource erstellen",
@@ -1502,6 +1511,10 @@
"actionListInvitations": "Einladungen auflisten",
"actionExportLogs": "Logs exportieren",
"actionViewLogs": "Logs anzeigen",
+ "actionCreateSiteProvisioningKey": "Bereitstellungsschlüssel für Standort erstellen",
+ "actionListSiteProvisioningKeys": "Liste der Bereitstellungsschlüssel für Standorte",
+ "actionUpdateSiteProvisioningKey": "Bereitstellungsschlüssel für Standort aktualisieren",
+ "actionDeleteSiteProvisioningKey": "Bereitstellungsschlüssel für Standort löschen",
"noneSelected": "Keine ausgewählt",
"orgNotFound2": "Keine Organisationen gefunden.",
"search": "Suche…",
@@ -1516,6 +1529,7 @@
"otpAuthDescription": "Geben Sie den Code aus Ihrer Authenticator-App oder einen Ihrer einmaligen Backup-Codes ein.",
"otpAuthSubmit": "Code absenden",
"idpContinue": "Oder weiter mit",
+ "idpLastUsed": "Zuletzt verwendet",
"otpAuthBack": "Zurück zum Passwort",
"navbar": "Navigationsmenü",
"navbarDescription": "Hauptnavigationsmenü für die Anwendung",
@@ -3801,5 +3815,6 @@
"rdpUploadFailed": "Upload fehlgeschlagen",
"rdpUnicodeKeyboardMode": "Unicode-Tastaturmodus",
"sessionToolbarShow": "Werkzeugleiste zeigen",
- "sessionToolbarHide": "Werkzeugleiste ausblenden"
+ "sessionToolbarHide": "Werkzeugleiste ausblenden",
+ "actionUpdateSiteApprovals": "Standortgenehmigungen aktualisieren"
}
diff --git a/messages/en-US.json b/messages/en-US.json
index 2a2c83b18..aff3be28b 100644
--- a/messages/en-US.json
+++ b/messages/en-US.json
@@ -178,7 +178,7 @@
"shareDeleteConfirm": "Confirm Delete Shareable Link",
"shareQuestionRemove": "Are you sure you want to delete this share link?",
"shareMessageRemove": "Once deleted, the link will no longer work and anyone using it will lose access to the resource.",
- "shareTokenDescription": "The access token can be passed in two ways: as a query parameter or in the request headers. These must be passed from the client on every request for authenticated access.",
+ "shareTokenDescription": "The access token can be passed as a query parameter or in request headers. By default it must be sent on every request. If session persistence is enabled, the first request exchanges it for a session cookie.",
"accessToken": "Access Token",
"usageExamples": "Usage Examples",
"tokenId": "Token ID",
@@ -196,8 +196,14 @@
"shareTitleOptional": "Title (optional)",
"sharePathOptional": "Path (optional)",
"sharePathDescription": "The link will redirect users to this path after authentication.",
+ "shareAssociateUserOptional": "Associate User (optional)",
+ "shareAssociateUserDescription": "When set, requests using this link are attributed to the user in access logs and identity headers. The link is removed if the user leaves the organization.",
+ "userSelect": "Select user",
+ "usersNotFound": "No users found",
"expireIn": "Expire In",
"neverExpire": "Never expire",
+ "sharePersistSession": "Persist session after first use",
+ "sharePersistSessionDescription": "When enabled, the first request with this token via a query param or header sets a session cookie so later requests do not need the token. Leave off for API clients that should send the token on every request.",
"shareExpireDescription": "Expiration time is how long the link will be usable and provide access to the resource. After this time, the link will no longer work, and users who used this link will lose access to the resource.",
"shareSeeOnce": "You will only be able to see this link once. Make sure to copy it.",
"shareAccessHint": "Anyone with this link can access the resource. Share it with care.",
@@ -449,8 +455,14 @@
"provisioningManage": "Provisioning",
"provisioningDescription": "Manage provisioning keys and review pending sites awaiting approval.",
"pendingSites": "Pending Sites",
- "siteApproveSuccess": "Site approved successfully",
+ "siteApproveSuccess": "Site and associated resources approved successfully",
"siteApproveError": "Error approving site",
+ "siteReject": "Reject Site",
+ "siteQuestionReject": "Are you sure you want to reject this site?",
+ "siteMessageReject": "This will permanently delete the site and any associated resources that are still pending.",
+ "siteConfirmReject": "Confirm Reject Site",
+ "siteRejectSuccess": "Site rejected successfully",
+ "siteRejectError": "Error rejecting site",
"provisioningKeys": "Provisioning Keys",
"searchProvisioningKeys": "Search provisioning keys...",
"provisioningKeysAdd": "Generate Provisioning Key",
@@ -466,12 +478,12 @@
"provisioningKeysSave": "Save the provisioning key",
"provisioningKeysSaveDescription": "You will only be able to see this once. Copy it to a secure place.",
"provisioningKeysErrorCreate": "Error creating provisioning key",
- "provisioningKeysList": "New provisioning key",
- "provisioningKeysMaxBatchSize": "Max batch size",
+ "provisioningKeysList": "New Provisioning Key",
+ "provisioningKeysMaxBatchSize": "Max Batch Size",
"provisioningKeysUnlimitedBatchSize": "Unlimited batch size (no limit)",
"provisioningKeysMaxBatchUnlimited": "Unlimited",
"provisioningKeysMaxBatchSizeInvalid": "Enter a valid max batch size (1–1,000,000).",
- "provisioningKeysValidUntil": "Valid until",
+ "provisioningKeysValidUntil": "Valid Until",
"provisioningKeysValidUntilHint": "Leave empty for no expiration.",
"provisioningKeysValidUntilInvalid": "Enter a valid date and time.",
"provisioningKeysNumUsed": "Times used",
@@ -480,7 +492,7 @@
"provisioningKeysNeverUsed": "Never",
"provisioningKeysEdit": "Edit Provisioning Key",
"provisioningKeysEditDescription": "Update the max batch size and expiration time for this key.",
- "provisioningKeysApproveNewSites": "Approve new sites",
+ "provisioningKeysApproveNewSites": "Approve New Sites",
"provisioningKeysApproveNewSitesDescription": "Automatically approve sites that register with this key.",
"provisioningKeysUpdateError": "Error updating provisioning key",
"provisioningKeysUpdated": "Provisioning key updated",
@@ -922,7 +934,7 @@
"newtVersion": "Version",
"architecture": "Architecture",
"sites": "Sites",
- "siteWgAnyClients": "Use any WireGuard client to connect. You will have to address internal resources using the peer IP.",
+ "siteWgAnyClients": "Use any WireGuard client to connect. You will have to address private resources using the peer IP.",
"siteWgCompatibleAllClients": "Compatible with all WireGuard clients",
"siteWgManualConfigurationRequired": "Manual configuration required",
"userErrorNotAdminOrOwner": "User is not an admin or owner",
@@ -1420,6 +1432,8 @@
"setupTokenDescription": "Enter the setup token from the server console.",
"setupTokenRequired": "Setup token is required",
"actionUpdateSite": "Update Site",
+ "actionApproveSite": "Approve Site",
+ "actionRejectSite": "Reject Site",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "List Allowed Site Roles",
"actionCreateResource": "Create Resource",
@@ -1503,6 +1517,10 @@
"actionListInvitations": "List Invitations",
"actionExportLogs": "Export Logs",
"actionViewLogs": "View Logs",
+ "actionCreateSiteProvisioningKey": "Create Site Provisioning Key",
+ "actionListSiteProvisioningKeys": "List Site Provisioning Keys",
+ "actionUpdateSiteProvisioningKey": "Update Site Provisioning Key",
+ "actionDeleteSiteProvisioningKey": "Delete Site Provisioning Key",
"noneSelected": "None selected",
"orgNotFound2": "No organizations found.",
"search": "Search…",
@@ -1517,6 +1535,7 @@
"otpAuthDescription": "Enter the code from your authenticator app or one of your single-use backup codes.",
"otpAuthSubmit": "Submit Code",
"idpContinue": "Or continue with",
+ "idpLastUsed": "Last Used",
"otpAuthBack": "Back to Password",
"navbar": "Navigation Menu",
"navbarDescription": "Main navigation menu for the application",
@@ -1976,6 +1995,9 @@
"domainPickerSubdomain": "Subdomain: {subdomain}",
"domainPickerNamespace": "Namespace: {namespace}",
"domainPickerShowMore": "Show More",
+ "domainPickerNoDomainsAvailableTitle": "No domains available",
+ "domainPickerNoDomainsAvailableDescription": "You don't have any domains set up yet. Create a domain to continue.",
+ "domainPickerNoDomainsAvailableAction": "Go to Domains",
"regionSelectorTitle": "Select Region",
"domainPickerRemoteExitNodeWarning": "Provided domains are not supported when sites connect to remote exit nodes. For resources to be available on remote nodes, use a custom domain instead.",
"regionSelectorInfo": "Selecting a region helps us provide better performance for your location. You do not have to be in the same region as your server.",
@@ -2339,7 +2361,7 @@
"resourcesTableProxyResources": "Public",
"resourcesTableClientResources": "Private",
"resourcesTableNoProxyResourcesFound": "No proxy resources found.",
- "resourcesTableNoInternalResourcesFound": "No internal resources found.",
+ "resourcesTableNoInternalResourcesFound": "No private resources found.",
"resourcesTableDestination": "Destination",
"resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Alias Address",
@@ -2362,9 +2384,9 @@
"editInternalResourceDialogCancel": "Cancel",
"editInternalResourceDialogSaveResource": "Save Resource",
"editInternalResourceDialogSuccess": "Success",
- "editInternalResourceDialogInternalResourceUpdatedSuccessfully": "Internal resource updated successfully",
+ "editInternalResourceDialogInternalResourceUpdatedSuccessfully": "Private resource updated successfully",
"editInternalResourceDialogError": "Error",
- "editInternalResourceDialogFailedToUpdateInternalResource": "Failed to update internal resource",
+ "editInternalResourceDialogFailedToUpdateInternalResource": "Failed to update private resource",
"editInternalResourceDialogNameRequired": "Name is required",
"editInternalResourceDialogNameMaxLength": "Name must be less than 255 characters",
"editInternalResourceDialogProxyPortMin": "Proxy port must be at least 1",
@@ -2390,7 +2412,7 @@
"editInternalResourceDialogAlias": "Alias",
"editInternalResourceDialogAliasDescription": "An optional internal DNS alias for this resource.",
"createInternalResourceDialogNoSitesAvailable": "No Sites Available",
- "createInternalResourceDialogNoSitesAvailableDescription": "You need to have at least one Newt site with a subnet configured to create internal resources.",
+ "createInternalResourceDialogNoSitesAvailableDescription": "You need to have at least one Newt site with a subnet configured to create private resources.",
"createInternalResourceDialogClose": "Close",
"createInternalResourceDialogCreateClientResource": "Create Private Resource",
"createInternalResourceDialogCreateClientResourceDescription": "Create a new resource that will only be accessible to clients connected to the organization",
@@ -2419,9 +2441,9 @@
"createInternalResourceDialogCancel": "Cancel",
"createInternalResourceDialogCreateResource": "Create Resource",
"createInternalResourceDialogSuccess": "Success",
- "createInternalResourceDialogInternalResourceCreatedSuccessfully": "Internal resource created successfully",
+ "createInternalResourceDialogInternalResourceCreatedSuccessfully": "Private resource created successfully",
"createInternalResourceDialogError": "Error",
- "createInternalResourceDialogFailedToCreateInternalResource": "Failed to create internal resource",
+ "createInternalResourceDialogFailedToCreateInternalResource": "Failed to create private resource",
"createInternalResourceDialogNameRequired": "Name is required",
"createInternalResourceDialogNameMaxLength": "Name must be less than 255 characters",
"createInternalResourceDialogPleaseSelectSite": "Please select a site",
@@ -3076,8 +3098,8 @@
"sourceAddress": "Source Address",
"destinationAddress": "Destination Address",
"duration": "Duration",
- "licenseRequiredToUse": "An + {t( + "shareAssociateUserDescription" + )} +
++ {t( + "sharePersistSessionDescription" + )} +
+{t("shareExpireDescription")}
diff --git a/src/components/DomainPicker.tsx b/src/components/DomainPicker.tsx index daacf892b..e06c3e57d 100644 --- a/src/components/DomainPicker.tsx +++ b/src/components/DomainPicker.tsx @@ -1,6 +1,6 @@ "use client"; -import { Alert, AlertDescription } from "@/components/ui/alert"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { @@ -43,10 +43,12 @@ import { CheckCircle2, ChevronsUpDown, ExternalLink, + Globe, KeyRound, Zap } from "lucide-react"; import { useTranslations } from "next-intl"; +import Link from "next/link"; import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert"; import { usePaidStatus } from "@/hooks/usePaidStatus"; import { TierFeature, tierMatrix } from "@server/lib/billing/tierMatrix"; @@ -494,6 +496,28 @@ export default function DomainPicker({ const hasMoreProvided = sortedAvailableOptions.length > providedDomainsShown; + const noDomainsAvailable = + !loadingDomains && + organizationDomains.length === 0 && + (build === "oss" || hideFreeDomain || requiresPaywall); + + if (noDomainsAvailable) { + return ( +{t("domainPickerNoDomainsAvailableDescription")}
+ +