mirror of
https://github.com/fosrl/pangolin.git
synced 2026-04-03 16:36:38 +00:00
Compare commits
65 Commits
1.17.0-rc.
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ce45a1acd | ||
|
|
a331dd3fb4 | ||
|
|
e3e2938b28 | ||
|
|
73e96b1b28 | ||
|
|
b8194295ec | ||
|
|
382a46dfff | ||
|
|
fee780cb81 | ||
|
|
5056cba85d | ||
|
|
dab38ff82c | ||
|
|
d83fa63af5 | ||
|
|
d5837ab718 | ||
|
|
f85cfc4c68 | ||
|
|
0b2aceafe0 | ||
|
|
059db34a53 | ||
|
|
bc1ea86b4e | ||
|
|
9f2ced1933 | ||
|
|
013cff9b6e | ||
|
|
aa19437031 | ||
|
|
e848ef848b | ||
|
|
bb6605337f | ||
|
|
8df8383468 | ||
|
|
a7e9de3ac4 | ||
|
|
8df41f514e | ||
|
|
c2bf50b121 | ||
|
|
4e7dcbd7b5 | ||
|
|
b7ccb92236 | ||
|
|
23a151dd45 | ||
|
|
122079ddb2 | ||
|
|
1d0b0ae6ec | ||
|
|
a55dd769cf | ||
|
|
f1a0bc97e3 | ||
|
|
a57dfd1d12 | ||
|
|
c0a8304b91 | ||
|
|
ab7b968e28 | ||
|
|
f10b40c3b0 | ||
|
|
7878ac9c76 | ||
|
|
0752951842 | ||
|
|
06bb6636a1 | ||
|
|
2fdd332a31 | ||
|
|
98b1e9546a | ||
|
|
184aa65c6d | ||
|
|
70b3a432a4 | ||
|
|
fb4fc75bd8 | ||
|
|
0479ed9e7f | ||
|
|
1dc3409135 | ||
|
|
1bb89fce26 | ||
|
|
8f3fbb94d2 | ||
|
|
e8c35bec1c | ||
|
|
728e7252eb | ||
|
|
1218507f7d | ||
|
|
a2dff0a35d | ||
|
|
f411180908 | ||
|
|
231a19b679 | ||
|
|
58a87a986a | ||
|
|
61a78ef352 | ||
|
|
e28e5ebb4e | ||
|
|
19cef8c453 | ||
|
|
1290d6cd5c | ||
|
|
ad301074db | ||
|
|
30a756d254 | ||
|
|
363c13c387 | ||
|
|
08e4afaef0 | ||
|
|
69aa6e2d1d | ||
|
|
547865e0da | ||
|
|
3a9e79e6d5 |
@@ -60,7 +60,7 @@ Pangolin is an open-source, identity-based remote access platform built on WireG
|
|||||||
|
|
||||||
| <img width=500 /> | Description |
|
| <img width=500 /> | Description |
|
||||||
|-----------------|--------------|
|
|-----------------|--------------|
|
||||||
| **Pangolin Cloud** | Fully managed service with instant setup and pay-as-you-go pricing — no infrastructure required. Or, self-host your own [remote node](https://docs.pangolin.net/manage/remote-node/understanding-nodes) and connect to our control plane. |
|
| **Pangolin Cloud** | Fully managed service with instant setup and pay-as-you-go pricing - no infrastructure required. Or, self-host your own [remote node](https://docs.pangolin.net/manage/remote-node/understanding-nodes) and connect to our control plane. |
|
||||||
| **Self-Host: Community Edition** | Free, open source, and licensed under AGPL-3. |
|
| **Self-Host: Community Edition** | Free, open source, and licensed under AGPL-3. |
|
||||||
| **Self-Host: Enterprise Edition** | Licensed under Fossorial Commercial License. Free for personal and hobbyist use, and for businesses earning under \$100K USD annually. |
|
| **Self-Host: Enterprise Edition** | Licensed under Fossorial Commercial License. Free for personal and hobbyist use, and for businesses earning under \$100K USD annually. |
|
||||||
|
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Ключът за осигуряване е актуализиран",
|
"provisioningKeysUpdated": "Ключът за осигуряване е актуализиран",
|
||||||
"provisioningKeysUpdatedDescription": "Вашите промени бяха запазени.",
|
"provisioningKeysUpdatedDescription": "Вашите промени бяха запазени.",
|
||||||
"provisioningKeysBannerTitle": "Ключове за осигуряване на сайта",
|
"provisioningKeysBannerTitle": "Ключове за осигуряване на сайта",
|
||||||
"provisioningKeysBannerDescription": "Генерирайте ключ за осигуряване и го използвайте с Newt конектора за автоматично създаване на сайтове при първото стартиране — няма нужда от създаване на отделни идентификационни данни за всеки сайт.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Научете повече",
|
"provisioningKeysBannerButtonText": "Научете повече",
|
||||||
"pendingSitesBannerTitle": "Чакащи сайтове",
|
"pendingSitesBannerTitle": "Чакащи сайтове",
|
||||||
"pendingSitesBannerDescription": "Сайтовете, които се свързват чрез ключ за осигуряване, се появяват тук за преглед. Одобрете всеки сайт, преди да стане активен и да получи достъп до вашите ресурси.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Научете повече",
|
"pendingSitesBannerButtonText": "Научете повече",
|
||||||
"apiKeysSettings": "Настройки на {apiKeyName}",
|
"apiKeysSettings": "Настройки на {apiKeyName}",
|
||||||
"userTitle": "Управление на всички потребители",
|
"userTitle": "Управление на всички потребители",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Моля, въведете валиден номер на порт",
|
"targetErrorInvalidPortDescription": "Моля, въведете валиден номер на порт",
|
||||||
"targetErrorNoSite": "Няма избран сайт",
|
"targetErrorNoSite": "Няма избран сайт",
|
||||||
"targetErrorNoSiteDescription": "Моля, изберете сайт за целта",
|
"targetErrorNoSiteDescription": "Моля, изберете сайт за целта",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Целта е създадена",
|
"targetCreated": "Целта е създадена",
|
||||||
"targetCreatedDescription": "Целта беше успешно създадена",
|
"targetCreatedDescription": "Целта беше успешно създадена",
|
||||||
"targetErrorCreate": "Неуспешно създаване на целта",
|
"targetErrorCreate": "Неуспешно създаване на целта",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Предприятие, 50 потребители, 50 сайта и приоритетна поддръжка."
|
"description": "Предприятие, 50 потребители, 50 сайта и приоритетна поддръжка."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Само за лична употреба (безплатен лиценз — без плащане)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Продължете към плащане"
|
"continueToCheckout": "Продължете към плащане"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Машинни клиенти",
|
"machineClients": "Машинни клиенти",
|
||||||
"install": "Инсталирай",
|
"install": "Инсталирай",
|
||||||
"run": "Изпълни",
|
"run": "Изпълни",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "Показваното име на клиента, което може да се промени по-късно.",
|
"clientNameDescription": "Показваното име на клиента, което може да се промени по-късно.",
|
||||||
"clientAddress": "Клиентски адрес (Разширено)",
|
"clientAddress": "Клиентски адрес (Разширено)",
|
||||||
"setupFailedToFetchSubnet": "Неуспешно извличане на подмрежа по подразбиране",
|
"setupFailedToFetchSubnet": "Неуспешно извличане на подмрежа по подразбиране",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Без удостоверяване",
|
"httpDestAuthNoneTitle": "Без удостоверяване",
|
||||||
"httpDestAuthNoneDescription": "Изпращане на заявки без заглавие за удостоверяване.",
|
"httpDestAuthNoneDescription": "Изпращане на заявки без заглавие за удостоверяване.",
|
||||||
"httpDestAuthBearerTitle": "Bearer Токен",
|
"httpDestAuthBearerTitle": "Bearer Токен",
|
||||||
"httpDestAuthBearerDescription": "Добавя заглавие за удостоверяване Bearer <token> към всяка заявка.",
|
"httpDestAuthBearerDescription": "Добавя заглавие за удостоверяване Bearer '<token>' към всяка заявка.",
|
||||||
"httpDestAuthBearerPlaceholder": "Вашият API ключ или токен",
|
"httpDestAuthBearerPlaceholder": "Вашият API ключ или токен",
|
||||||
"httpDestAuthBasicTitle": "Основно удостоверяване",
|
"httpDestAuthBasicTitle": "Основно удостоверяване",
|
||||||
"httpDestAuthBasicDescription": "Добавя заглавие за удостоверяване Basic <credentials> към всяка заявка. Осигурете идентификационни данни като потребителско име:парола.",
|
"httpDestAuthBasicDescription": "Добавя заглавие за удостоверяване Basic '<credentials>' към всяка заявка. Осигурете идентификационни данни като потребителско име:парола.",
|
||||||
"httpDestAuthBasicPlaceholder": "потребителско име:парола",
|
"httpDestAuthBasicPlaceholder": "потребителско име:парола",
|
||||||
"httpDestAuthCustomTitle": "Персонализирано заглавие",
|
"httpDestAuthCustomTitle": "Персонализирано заглавие",
|
||||||
"httpDestAuthCustomDescription": "Посочете персонализирано име и стойност на заглавието за удостоверяване (например X-API-Key).",
|
"httpDestAuthCustomDescription": "Посочете персонализирано име и стойност на заглавието за удостоверяване (например X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Zajišťovací klíč byl aktualizován",
|
"provisioningKeysUpdated": "Zajišťovací klíč byl aktualizován",
|
||||||
"provisioningKeysUpdatedDescription": "Vaše změny byly uloženy.",
|
"provisioningKeysUpdatedDescription": "Vaše změny byly uloženy.",
|
||||||
"provisioningKeysBannerTitle": "Klíče pro poskytování webu",
|
"provisioningKeysBannerTitle": "Klíče pro poskytování webu",
|
||||||
"provisioningKeysBannerDescription": "Vygenerujte konfigurační klíč a používejte jej pomocí nového konektoru k automatickému vytváření stránek při prvním startu – není třeba nastavovat samostatné přihlašovací údaje pro každý web.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Zjistit více",
|
"provisioningKeysBannerButtonText": "Zjistit více",
|
||||||
"pendingSitesBannerTitle": "Nevyřízené weby",
|
"pendingSitesBannerTitle": "Nevyřízené weby",
|
||||||
"pendingSitesBannerDescription": "Zde se zobrazují stránky, které se připojují pomocí doplňovacího klíče. Schválte každý web předtím, než bude aktivní, a získejte přístup k vašim zdrojům.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Zjistit více",
|
"pendingSitesBannerButtonText": "Zjistit více",
|
||||||
"apiKeysSettings": "Nastavení {apiKeyName}",
|
"apiKeysSettings": "Nastavení {apiKeyName}",
|
||||||
"userTitle": "Spravovat všechny uživatele",
|
"userTitle": "Spravovat všechny uživatele",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Zadejte platné číslo portu",
|
"targetErrorInvalidPortDescription": "Zadejte platné číslo portu",
|
||||||
"targetErrorNoSite": "Není vybrán žádný web",
|
"targetErrorNoSite": "Není vybrán žádný web",
|
||||||
"targetErrorNoSiteDescription": "Vyberte prosím web pro cíl",
|
"targetErrorNoSiteDescription": "Vyberte prosím web pro cíl",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Cíl byl vytvořen",
|
"targetCreated": "Cíl byl vytvořen",
|
||||||
"targetCreatedDescription": "Cíl byl úspěšně vytvořen",
|
"targetCreatedDescription": "Cíl byl úspěšně vytvořen",
|
||||||
"targetErrorCreate": "Nepodařilo se vytvořit cíl",
|
"targetErrorCreate": "Nepodařilo se vytvořit cíl",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Podnikové funkce, 50 uživatelů, 50 míst a prioritní podpory."
|
"description": "Podnikové funkce, 50 uživatelů, 50 míst a prioritní podpory."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Pouze osobní použití (bezplatná licence – bez platby)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Pokračovat do pokladny"
|
"continueToCheckout": "Pokračovat do pokladny"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Strojoví klienti",
|
"machineClients": "Strojoví klienti",
|
||||||
"install": "Instalovat",
|
"install": "Instalovat",
|
||||||
"run": "Spustit",
|
"run": "Spustit",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "Zobrazované jméno klienta, které lze později změnit.",
|
"clientNameDescription": "Zobrazované jméno klienta, které lze později změnit.",
|
||||||
"clientAddress": "Adresa klienta (Rozšířeno)",
|
"clientAddress": "Adresa klienta (Rozšířeno)",
|
||||||
"setupFailedToFetchSubnet": "Nepodařilo se načíst výchozí podsíť",
|
"setupFailedToFetchSubnet": "Nepodařilo se načíst výchozí podsíť",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Žádné ověření",
|
"httpDestAuthNoneTitle": "Žádné ověření",
|
||||||
"httpDestAuthNoneDescription": "Odešle žádosti bez záhlaví autorizace.",
|
"httpDestAuthNoneDescription": "Odešle žádosti bez záhlaví autorizace.",
|
||||||
"httpDestAuthBearerTitle": "Token na doručitele",
|
"httpDestAuthBearerTitle": "Token na doručitele",
|
||||||
"httpDestAuthBearerDescription": "Přidá autorizaci: Hlavička Bearer <token> ke každému požadavku.",
|
"httpDestAuthBearerDescription": "Přidá autorizaci: Hlavička Bearer '<token>' ke každému požadavku.",
|
||||||
"httpDestAuthBearerPlaceholder": "Váš API klíč nebo token",
|
"httpDestAuthBearerPlaceholder": "Váš API klíč nebo token",
|
||||||
"httpDestAuthBasicTitle": "Základní ověření",
|
"httpDestAuthBasicTitle": "Základní ověření",
|
||||||
"httpDestAuthBasicDescription": "Přidá autorizaci: Základní <credentials> hlavička. Poskytněte přihlašovací údaje jako uživatelské jméno:password.",
|
"httpDestAuthBasicDescription": "Přidá autorizaci: Základní '<credentials>' hlavička. Poskytněte přihlašovací údaje jako uživatelské jméno:password.",
|
||||||
"httpDestAuthBasicPlaceholder": "uživatelské jméno:heslo",
|
"httpDestAuthBasicPlaceholder": "uživatelské jméno:heslo",
|
||||||
"httpDestAuthCustomTitle": "Vlastní záhlaví",
|
"httpDestAuthCustomTitle": "Vlastní záhlaví",
|
||||||
"httpDestAuthCustomDescription": "Zadejte název a hodnotu vlastního HTTP hlavičky pro ověření (např. X-API-Key).",
|
"httpDestAuthCustomDescription": "Zadejte název a hodnotu vlastního HTTP hlavičky pro ověření (např. X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Bereitstellungsschlüssel aktualisiert",
|
"provisioningKeysUpdated": "Bereitstellungsschlüssel aktualisiert",
|
||||||
"provisioningKeysUpdatedDescription": "Ihre Änderungen wurden gespeichert.",
|
"provisioningKeysUpdatedDescription": "Ihre Änderungen wurden gespeichert.",
|
||||||
"provisioningKeysBannerTitle": "Website-Bereitstellungsschlüssel",
|
"provisioningKeysBannerTitle": "Website-Bereitstellungsschlüssel",
|
||||||
"provisioningKeysBannerDescription": "Generieren Sie einen Bereitstellungsschlüssel und verwenden Sie ihn mit dem Newt-Konnektor, um beim ersten Start automatisch Sites zu erstellen – keine Notwendigkeit, separate Anmeldeinformationen für jede Seite einzurichten.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Mehr erfahren",
|
"provisioningKeysBannerButtonText": "Mehr erfahren",
|
||||||
"pendingSitesBannerTitle": "Ausstehende Seiten",
|
"pendingSitesBannerTitle": "Ausstehende Seiten",
|
||||||
"pendingSitesBannerDescription": "Sites, die sich mit einem Bereitstellungsschlüssel verbinden, erscheinen hier zur Überprüfung. Bestätigen Sie jede Site, bevor sie aktiv wird und erhalten Zugriff auf Ihre Ressourcen.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Mehr erfahren",
|
"pendingSitesBannerButtonText": "Mehr erfahren",
|
||||||
"apiKeysSettings": "{apiKeyName} Einstellungen",
|
"apiKeysSettings": "{apiKeyName} Einstellungen",
|
||||||
"userTitle": "Alle Benutzer verwalten",
|
"userTitle": "Alle Benutzer verwalten",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Bitte geben Sie eine gültige Portnummer ein",
|
"targetErrorInvalidPortDescription": "Bitte geben Sie eine gültige Portnummer ein",
|
||||||
"targetErrorNoSite": "Kein Standort ausgewählt",
|
"targetErrorNoSite": "Kein Standort ausgewählt",
|
||||||
"targetErrorNoSiteDescription": "Bitte wähle einen Standort für das Ziel aus",
|
"targetErrorNoSiteDescription": "Bitte wähle einen Standort für das Ziel aus",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Ziel erstellt",
|
"targetCreated": "Ziel erstellt",
|
||||||
"targetCreatedDescription": "Ziel wurde erfolgreich erstellt",
|
"targetCreatedDescription": "Ziel wurde erfolgreich erstellt",
|
||||||
"targetErrorCreate": "Fehler beim Erstellen des Ziels",
|
"targetErrorCreate": "Fehler beim Erstellen des Ziels",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Enterprise Features, 50 Benutzer, 50 Sites und Prioritätsunterstützung."
|
"description": "Enterprise Features, 50 Benutzer, 50 Sites und Prioritätsunterstützung."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Nur persönliche Nutzung (kostenlose Lizenz — keine Kasse)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Weiter zur Kasse"
|
"continueToCheckout": "Weiter zur Kasse"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Maschinen-Clients",
|
"machineClients": "Maschinen-Clients",
|
||||||
"install": "Installieren",
|
"install": "Installieren",
|
||||||
"run": "Ausführen",
|
"run": "Ausführen",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "Der Anzeigename des Clients, der später geändert werden kann.",
|
"clientNameDescription": "Der Anzeigename des Clients, der später geändert werden kann.",
|
||||||
"clientAddress": "Clientadresse (Erweitert)",
|
"clientAddress": "Clientadresse (Erweitert)",
|
||||||
"setupFailedToFetchSubnet": "Fehler beim Abrufen des Standard-Subnetzes",
|
"setupFailedToFetchSubnet": "Fehler beim Abrufen des Standard-Subnetzes",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Keine Authentifizierung",
|
"httpDestAuthNoneTitle": "Keine Authentifizierung",
|
||||||
"httpDestAuthNoneDescription": "Sendet Anfragen ohne Autorisierungs-Header.",
|
"httpDestAuthNoneDescription": "Sendet Anfragen ohne Autorisierungs-Header.",
|
||||||
"httpDestAuthBearerTitle": "Bären-Token",
|
"httpDestAuthBearerTitle": "Bären-Token",
|
||||||
"httpDestAuthBearerDescription": "Fügt eine Berechtigung hinzu: Bearer <token> Header zu jeder Anfrage.",
|
"httpDestAuthBearerDescription": "Fügt eine Berechtigung hinzu: Bearer '<token>' Header zu jeder Anfrage.",
|
||||||
"httpDestAuthBearerPlaceholder": "Ihr API-Schlüssel oder Token",
|
"httpDestAuthBearerPlaceholder": "Ihr API-Schlüssel oder Token",
|
||||||
"httpDestAuthBasicTitle": "Einfacher Auth",
|
"httpDestAuthBasicTitle": "Einfacher Auth",
|
||||||
"httpDestAuthBasicDescription": "Fügt eine Autorisierung hinzu: Basic <credentials> Kopfzeile hinzu. Geben Sie Anmeldedaten als Benutzername:password an.",
|
"httpDestAuthBasicDescription": "Fügt eine Autorisierung hinzu: Basic '<credentials>' Kopfzeile hinzu. Geben Sie Anmeldedaten als Benutzername:password an.",
|
||||||
"httpDestAuthBasicPlaceholder": "benutzername:password",
|
"httpDestAuthBasicPlaceholder": "benutzername:password",
|
||||||
"httpDestAuthCustomTitle": "Eigene Kopfzeile",
|
"httpDestAuthCustomTitle": "Eigene Kopfzeile",
|
||||||
"httpDestAuthCustomDescription": "Geben Sie einen eigenen HTTP-Header-Namen und einen Wert für die Authentifizierung an (z.B. X-API-Key).",
|
"httpDestAuthCustomDescription": "Geben Sie einen eigenen HTTP-Header-Namen und einen Wert für die Authentifizierung an (z.B. X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Provisioning key updated",
|
"provisioningKeysUpdated": "Provisioning key updated",
|
||||||
"provisioningKeysUpdatedDescription": "Your changes have been saved.",
|
"provisioningKeysUpdatedDescription": "Your changes have been saved.",
|
||||||
"provisioningKeysBannerTitle": "Site Provisioning Keys",
|
"provisioningKeysBannerTitle": "Site Provisioning Keys",
|
||||||
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup — no need to set up separate credentials for each site.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Learn More",
|
"provisioningKeysBannerButtonText": "Learn More",
|
||||||
"pendingSitesBannerTitle": "Pending Sites",
|
"pendingSitesBannerTitle": "Pending Sites",
|
||||||
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review. Approve each site before it becomes active and gains access to your resources.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Learn More",
|
"pendingSitesBannerButtonText": "Learn More",
|
||||||
"apiKeysSettings": "{apiKeyName} Settings",
|
"apiKeysSettings": "{apiKeyName} Settings",
|
||||||
"userTitle": "Manage All Users",
|
"userTitle": "Manage All Users",
|
||||||
@@ -2348,7 +2348,7 @@
|
|||||||
"description": "Enterprise features, 50 users, 50 sites, and priority support."
|
"description": "Enterprise features, 50 users, 50 sites, and priority support."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Personal use only (free license — no checkout)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Continue to Checkout"
|
"continueToCheckout": "Continue to Checkout"
|
||||||
},
|
},
|
||||||
@@ -2609,6 +2609,9 @@
|
|||||||
"machineClients": "Machine Clients",
|
"machineClients": "Machine Clients",
|
||||||
"install": "Install",
|
"install": "Install",
|
||||||
"run": "Run",
|
"run": "Run",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "The display name of the client that can be changed later.",
|
"clientNameDescription": "The display name of the client that can be changed later.",
|
||||||
"clientAddress": "Client Address (Advanced)",
|
"clientAddress": "Client Address (Advanced)",
|
||||||
"setupFailedToFetchSubnet": "Failed to fetch default subnet",
|
"setupFailedToFetchSubnet": "Failed to fetch default subnet",
|
||||||
@@ -2847,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "No Authentication",
|
"httpDestAuthNoneTitle": "No Authentication",
|
||||||
"httpDestAuthNoneDescription": "Sends requests without an Authorization header.",
|
"httpDestAuthNoneDescription": "Sends requests without an Authorization header.",
|
||||||
"httpDestAuthBearerTitle": "Bearer Token",
|
"httpDestAuthBearerTitle": "Bearer Token",
|
||||||
"httpDestAuthBearerDescription": "Adds an Authorization: Bearer <token> header to each request.",
|
"httpDestAuthBearerDescription": "Adds an Authorization: Bearer '<token>' header to each request.",
|
||||||
"httpDestAuthBearerPlaceholder": "Your API key or token",
|
"httpDestAuthBearerPlaceholder": "Your API key or token",
|
||||||
"httpDestAuthBasicTitle": "Basic Auth",
|
"httpDestAuthBasicTitle": "Basic Auth",
|
||||||
"httpDestAuthBasicDescription": "Adds an Authorization: Basic <credentials> header. Provide credentials as username:password.",
|
"httpDestAuthBasicDescription": "Adds an Authorization: Basic '<credentials>' header. Provide credentials as username:password.",
|
||||||
"httpDestAuthBasicPlaceholder": "username:password",
|
"httpDestAuthBasicPlaceholder": "username:password",
|
||||||
"httpDestAuthCustomTitle": "Custom Header",
|
"httpDestAuthCustomTitle": "Custom Header",
|
||||||
"httpDestAuthCustomDescription": "Specify a custom HTTP header name and value for authentication (e.g. X-API-Key).",
|
"httpDestAuthCustomDescription": "Specify a custom HTTP header name and value for authentication (e.g. X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Clave de aprovisionamiento actualizada",
|
"provisioningKeysUpdated": "Clave de aprovisionamiento actualizada",
|
||||||
"provisioningKeysUpdatedDescription": "Sus cambios han sido guardados.",
|
"provisioningKeysUpdatedDescription": "Sus cambios han sido guardados.",
|
||||||
"provisioningKeysBannerTitle": "Claves de aprovisionamiento del sitio",
|
"provisioningKeysBannerTitle": "Claves de aprovisionamiento del sitio",
|
||||||
"provisioningKeysBannerDescription": "Generar una clave de aprovisionamiento y usarla con el conector Newt para crear automáticamente sitios en el primer inicio — no es necesario configurar credenciales separadas para cada sitio.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Saber más",
|
"provisioningKeysBannerButtonText": "Saber más",
|
||||||
"pendingSitesBannerTitle": "Sitios pendientes",
|
"pendingSitesBannerTitle": "Sitios pendientes",
|
||||||
"pendingSitesBannerDescription": "Los sitios que se conectan usando una clave de aprovisionamiento aparecen aquí para su revisión. Aprobar cada sitio antes de que se active y obtenga acceso a sus recursos.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Saber más",
|
"pendingSitesBannerButtonText": "Saber más",
|
||||||
"apiKeysSettings": "Ajustes {apiKeyName}",
|
"apiKeysSettings": "Ajustes {apiKeyName}",
|
||||||
"userTitle": "Administrar todos los usuarios",
|
"userTitle": "Administrar todos los usuarios",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Por favor, introduzca un número de puerto válido",
|
"targetErrorInvalidPortDescription": "Por favor, introduzca un número de puerto válido",
|
||||||
"targetErrorNoSite": "Ningún sitio seleccionado",
|
"targetErrorNoSite": "Ningún sitio seleccionado",
|
||||||
"targetErrorNoSiteDescription": "Por favor, seleccione un sitio para el objetivo",
|
"targetErrorNoSiteDescription": "Por favor, seleccione un sitio para el objetivo",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Objetivo creado",
|
"targetCreated": "Objetivo creado",
|
||||||
"targetCreatedDescription": "El objetivo se ha creado correctamente",
|
"targetCreatedDescription": "El objetivo se ha creado correctamente",
|
||||||
"targetErrorCreate": "Error al crear el objetivo",
|
"targetErrorCreate": "Error al crear el objetivo",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Características de la empresa, 50 usuarios, 50 sitios y soporte prioritario."
|
"description": "Características de la empresa, 50 usuarios, 50 sitios y soporte prioritario."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Solo uso personal (licencia gratuita, sin pago)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Continuar con el pago"
|
"continueToCheckout": "Continuar con el pago"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Clientes de la máquina",
|
"machineClients": "Clientes de la máquina",
|
||||||
"install": "Instalar",
|
"install": "Instalar",
|
||||||
"run": "Ejecutar",
|
"run": "Ejecutar",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "El nombre mostrado del cliente que se puede cambiar más adelante.",
|
"clientNameDescription": "El nombre mostrado del cliente que se puede cambiar más adelante.",
|
||||||
"clientAddress": "Dirección del cliente (Avanzado)",
|
"clientAddress": "Dirección del cliente (Avanzado)",
|
||||||
"setupFailedToFetchSubnet": "No se pudo obtener la subred por defecto",
|
"setupFailedToFetchSubnet": "No se pudo obtener la subred por defecto",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Sin autenticación",
|
"httpDestAuthNoneTitle": "Sin autenticación",
|
||||||
"httpDestAuthNoneDescription": "Envía solicitudes sin un encabezado de autorización.",
|
"httpDestAuthNoneDescription": "Envía solicitudes sin un encabezado de autorización.",
|
||||||
"httpDestAuthBearerTitle": "Tóken de portador",
|
"httpDestAuthBearerTitle": "Tóken de portador",
|
||||||
"httpDestAuthBearerDescription": "Añade una autorización: portador <token> encabezado a cada solicitud.",
|
"httpDestAuthBearerDescription": "Añade una autorización: portador '<token>' encabezado a cada solicitud.",
|
||||||
"httpDestAuthBearerPlaceholder": "Tu clave o token API",
|
"httpDestAuthBearerPlaceholder": "Tu clave o token API",
|
||||||
"httpDestAuthBasicTitle": "Auth Básica",
|
"httpDestAuthBasicTitle": "Auth Básica",
|
||||||
"httpDestAuthBasicDescription": "Añade una Autorización: encabezado básico <credentials> . Proporcione credenciales como nombre de usuario: contraseña.",
|
"httpDestAuthBasicDescription": "Añade una Autorización: encabezado básico '<credentials>' . Proporcione credenciales como nombre de usuario: contraseña.",
|
||||||
"httpDestAuthBasicPlaceholder": "usuario:contraseña",
|
"httpDestAuthBasicPlaceholder": "usuario:contraseña",
|
||||||
"httpDestAuthCustomTitle": "Cabecera personalizada",
|
"httpDestAuthCustomTitle": "Cabecera personalizada",
|
||||||
"httpDestAuthCustomDescription": "Especifique un nombre de cabecera HTTP personalizado y un valor para la autenticación (por ejemplo, X-API-Key).",
|
"httpDestAuthCustomDescription": "Especifique un nombre de cabecera HTTP personalizado y un valor para la autenticación (por ejemplo, X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Clé de provisioning mise à jour",
|
"provisioningKeysUpdated": "Clé de provisioning mise à jour",
|
||||||
"provisioningKeysUpdatedDescription": "Vos modifications ont été enregistrées.",
|
"provisioningKeysUpdatedDescription": "Vos modifications ont été enregistrées.",
|
||||||
"provisioningKeysBannerTitle": "Clés de provisioning du site",
|
"provisioningKeysBannerTitle": "Clés de provisioning du site",
|
||||||
"provisioningKeysBannerDescription": "Générez une clé de provisioning et utilisez-la avec le connecteur Newt pour créer automatiquement des sites au premier démarrage — pas besoin de configurer des identifiants distincts pour chaque site.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "En savoir plus",
|
"provisioningKeysBannerButtonText": "En savoir plus",
|
||||||
"pendingSitesBannerTitle": "Sites en attente",
|
"pendingSitesBannerTitle": "Sites en attente",
|
||||||
"pendingSitesBannerDescription": "Les sites qui se connectent à l'aide d'une clé de provisioning apparaissent ici pour être revus. Approuver chaque site avant qu'il ne devienne actif et qu'il accède à vos ressources.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "En savoir plus",
|
"pendingSitesBannerButtonText": "En savoir plus",
|
||||||
"apiKeysSettings": "Paramètres de {apiKeyName}",
|
"apiKeysSettings": "Paramètres de {apiKeyName}",
|
||||||
"userTitle": "Gérer tous les utilisateurs",
|
"userTitle": "Gérer tous les utilisateurs",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Veuillez entrer un numéro de port valide",
|
"targetErrorInvalidPortDescription": "Veuillez entrer un numéro de port valide",
|
||||||
"targetErrorNoSite": "Aucun site sélectionné",
|
"targetErrorNoSite": "Aucun site sélectionné",
|
||||||
"targetErrorNoSiteDescription": "Veuillez sélectionner un site pour la cible",
|
"targetErrorNoSiteDescription": "Veuillez sélectionner un site pour la cible",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Cible créée",
|
"targetCreated": "Cible créée",
|
||||||
"targetCreatedDescription": "La cible a été créée avec succès",
|
"targetCreatedDescription": "La cible a été créée avec succès",
|
||||||
"targetErrorCreate": "Impossible de créer la cible",
|
"targetErrorCreate": "Impossible de créer la cible",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Fonctionnalités d'entreprise, 50 utilisateurs, 50 sites et une prise en charge prioritaire."
|
"description": "Fonctionnalités d'entreprise, 50 utilisateurs, 50 sites et une prise en charge prioritaire."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Utilisation personnelle uniquement (licence gratuite — sans checkout)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Continuer vers le paiement"
|
"continueToCheckout": "Continuer vers le paiement"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Clients Machines",
|
"machineClients": "Clients Machines",
|
||||||
"install": "Installer",
|
"install": "Installer",
|
||||||
"run": "Exécuter",
|
"run": "Exécuter",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "Le nom d'affichage du client qui peut être modifié plus tard.",
|
"clientNameDescription": "Le nom d'affichage du client qui peut être modifié plus tard.",
|
||||||
"clientAddress": "Adresse du client (Avancé)",
|
"clientAddress": "Adresse du client (Avancé)",
|
||||||
"setupFailedToFetchSubnet": "Impossible de récupérer le sous-réseau par défaut",
|
"setupFailedToFetchSubnet": "Impossible de récupérer le sous-réseau par défaut",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Aucune authentification",
|
"httpDestAuthNoneTitle": "Aucune authentification",
|
||||||
"httpDestAuthNoneDescription": "Envoie des requêtes sans en-tête d'autorisation.",
|
"httpDestAuthNoneDescription": "Envoie des requêtes sans en-tête d'autorisation.",
|
||||||
"httpDestAuthBearerTitle": "Jeton de Porteur",
|
"httpDestAuthBearerTitle": "Jeton de Porteur",
|
||||||
"httpDestAuthBearerDescription": "Ajoute un en-tête Authorization: Bearer <token> à chaque requête.",
|
"httpDestAuthBearerDescription": "Ajoute un en-tête Authorization: Bearer '<token>' à chaque requête.",
|
||||||
"httpDestAuthBearerPlaceholder": "Votre clé API ou votre jeton",
|
"httpDestAuthBearerPlaceholder": "Votre clé API ou votre jeton",
|
||||||
"httpDestAuthBasicTitle": "Authentification basique",
|
"httpDestAuthBasicTitle": "Authentification basique",
|
||||||
"httpDestAuthBasicDescription": "Ajoute une autorisation : en-tête de base <credentials> . Fournissez des informations d'identification comme nom d'utilisateur:mot de passe.",
|
"httpDestAuthBasicDescription": "Ajoute une autorisation : en-tête de base '<credentials>' . Fournissez des informations d'identification comme nom d'utilisateur:mot de passe.",
|
||||||
"httpDestAuthBasicPlaceholder": "nom d'utilisateur:mot de passe",
|
"httpDestAuthBasicPlaceholder": "nom d'utilisateur:mot de passe",
|
||||||
"httpDestAuthCustomTitle": "En-tête personnalisé",
|
"httpDestAuthCustomTitle": "En-tête personnalisé",
|
||||||
"httpDestAuthCustomDescription": "Spécifiez un nom d'en-tête HTTP personnalisé et une valeur pour l'authentification (par exemple X-API-Key).",
|
"httpDestAuthCustomDescription": "Spécifiez un nom d'en-tête HTTP personnalisé et une valeur pour l'authentification (par exemple X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Chiave di accantonamento aggiornata",
|
"provisioningKeysUpdated": "Chiave di accantonamento aggiornata",
|
||||||
"provisioningKeysUpdatedDescription": "Le tue modifiche sono state salvate.",
|
"provisioningKeysUpdatedDescription": "Le tue modifiche sono state salvate.",
|
||||||
"provisioningKeysBannerTitle": "Chiavi Di Provvedimento Sito",
|
"provisioningKeysBannerTitle": "Chiavi Di Provvedimento Sito",
|
||||||
"provisioningKeysBannerDescription": "Generare una chiave di provisioning e usarla con il connettore Newt per creare automaticamente siti al primo avvio — non è necessario impostare credenziali separate per ogni sito.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Scopri di più",
|
"provisioningKeysBannerButtonText": "Scopri di più",
|
||||||
"pendingSitesBannerTitle": "Siti In Attesa",
|
"pendingSitesBannerTitle": "Siti In Attesa",
|
||||||
"pendingSitesBannerDescription": "I siti che si connettono utilizzando una chiave di provisioning appaiono qui per la revisione. Approva ogni sito prima che diventi attivo e ottenga l'accesso alle tue risorse.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Scopri di più",
|
"pendingSitesBannerButtonText": "Scopri di più",
|
||||||
"apiKeysSettings": "Impostazioni {apiKeyName}",
|
"apiKeysSettings": "Impostazioni {apiKeyName}",
|
||||||
"userTitle": "Gestisci Tutti Gli Utenti",
|
"userTitle": "Gestisci Tutti Gli Utenti",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Inserisci un numero di porta valido",
|
"targetErrorInvalidPortDescription": "Inserisci un numero di porta valido",
|
||||||
"targetErrorNoSite": "Nessun sito selezionato",
|
"targetErrorNoSite": "Nessun sito selezionato",
|
||||||
"targetErrorNoSiteDescription": "Si prega di selezionare un sito per l'obiettivo",
|
"targetErrorNoSiteDescription": "Si prega di selezionare un sito per l'obiettivo",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Destinazione creata",
|
"targetCreated": "Destinazione creata",
|
||||||
"targetCreatedDescription": "L'obiettivo è stato creato con successo",
|
"targetCreatedDescription": "L'obiettivo è stato creato con successo",
|
||||||
"targetErrorCreate": "Impossibile creare l'obiettivo",
|
"targetErrorCreate": "Impossibile creare l'obiettivo",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Funzionalità aziendali, 50 utenti, 50 siti e supporto prioritario."
|
"description": "Funzionalità aziendali, 50 utenti, 50 siti e supporto prioritario."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Solo uso personale (licenza gratuita — nessun checkout)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Continua al Checkout"
|
"continueToCheckout": "Continua al Checkout"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Machine Clients",
|
"machineClients": "Machine Clients",
|
||||||
"install": "Installa",
|
"install": "Installa",
|
||||||
"run": "Esegui",
|
"run": "Esegui",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "Il nome visualizzato del client che può essere modificato in seguito.",
|
"clientNameDescription": "Il nome visualizzato del client che può essere modificato in seguito.",
|
||||||
"clientAddress": "Indirizzo Client (Avanzato)",
|
"clientAddress": "Indirizzo Client (Avanzato)",
|
||||||
"setupFailedToFetchSubnet": "Recupero della sottorete predefinita non riuscito",
|
"setupFailedToFetchSubnet": "Recupero della sottorete predefinita non riuscito",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Nessuna Autenticazione",
|
"httpDestAuthNoneTitle": "Nessuna Autenticazione",
|
||||||
"httpDestAuthNoneDescription": "Invia richieste senza intestazione autorizzazione.",
|
"httpDestAuthNoneDescription": "Invia richieste senza intestazione autorizzazione.",
|
||||||
"httpDestAuthBearerTitle": "Token Del Portatore",
|
"httpDestAuthBearerTitle": "Token Del Portatore",
|
||||||
"httpDestAuthBearerDescription": "Aggiunge un'intestazione Autorizzazione: Bearer <token> ad ogni richiesta.",
|
"httpDestAuthBearerDescription": "Aggiunge un'intestazione Autorizzazione: Bearer '<token>' ad ogni richiesta.",
|
||||||
"httpDestAuthBearerPlaceholder": "La tua chiave API o token",
|
"httpDestAuthBearerPlaceholder": "La tua chiave API o token",
|
||||||
"httpDestAuthBasicTitle": "Autenticazione Base",
|
"httpDestAuthBasicTitle": "Autenticazione Base",
|
||||||
"httpDestAuthBasicDescription": "Aggiunge un'autorizzazione: intestazione di base <credentials> . Fornisce le credenziali come username:password.",
|
"httpDestAuthBasicDescription": "Aggiunge un'autorizzazione: intestazione di base '<credentials>' . Fornisce le credenziali come username:password.",
|
||||||
"httpDestAuthBasicPlaceholder": "username:password",
|
"httpDestAuthBasicPlaceholder": "username:password",
|
||||||
"httpDestAuthCustomTitle": "Intestazione Personalizzata",
|
"httpDestAuthCustomTitle": "Intestazione Personalizzata",
|
||||||
"httpDestAuthCustomDescription": "Specifica un nome e un valore di intestazione HTTP personalizzati per l'autenticazione (ad esempio X-API-Key).",
|
"httpDestAuthCustomDescription": "Specifica un nome e un valore di intestazione HTTP personalizzati per l'autenticazione (ad esempio X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "프로비저닝 키가 업데이트되었습니다",
|
"provisioningKeysUpdated": "프로비저닝 키가 업데이트되었습니다",
|
||||||
"provisioningKeysUpdatedDescription": "변경 사항이 저장되었습니다.",
|
"provisioningKeysUpdatedDescription": "변경 사항이 저장되었습니다.",
|
||||||
"provisioningKeysBannerTitle": "사이트 프로비저닝 키",
|
"provisioningKeysBannerTitle": "사이트 프로비저닝 키",
|
||||||
"provisioningKeysBannerDescription": "프로비저닝 키를 생성하여 Newt 커넥터와 함께 사용해 첫 실행 시 자동으로 사이트를 생성하세요 — 각 사이트마다 별도의 인증을 설정할 필요가 없습니다.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "자세히 알아보기",
|
"provisioningKeysBannerButtonText": "자세히 알아보기",
|
||||||
"pendingSitesBannerTitle": "대기중인 사이트",
|
"pendingSitesBannerTitle": "대기중인 사이트",
|
||||||
"pendingSitesBannerDescription": "프로비저닝 키를 사용하여 연결하는 사이트는 검토 대기 중입니다. 사이트가 활성화되어 리소스에 액세스하기 전에 각 사이트를 승인하세요.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "자세히 알아보기",
|
"pendingSitesBannerButtonText": "자세히 알아보기",
|
||||||
"apiKeysSettings": "{apiKeyName} 설정",
|
"apiKeysSettings": "{apiKeyName} 설정",
|
||||||
"userTitle": "모든 사용자 관리",
|
"userTitle": "모든 사용자 관리",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "유효한 포트 번호를 입력하세요.",
|
"targetErrorInvalidPortDescription": "유효한 포트 번호를 입력하세요.",
|
||||||
"targetErrorNoSite": "선택된 사이트 없음",
|
"targetErrorNoSite": "선택된 사이트 없음",
|
||||||
"targetErrorNoSiteDescription": "대상을 위해 사이트를 선택하세요.",
|
"targetErrorNoSiteDescription": "대상을 위해 사이트를 선택하세요.",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "대상 생성",
|
"targetCreated": "대상 생성",
|
||||||
"targetCreatedDescription": "대상이 성공적으로 생성되었습니다.",
|
"targetCreatedDescription": "대상이 성공적으로 생성되었습니다.",
|
||||||
"targetErrorCreate": "대상 생성 실패",
|
"targetErrorCreate": "대상 생성 실패",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "기업 기능, 50명의 사용자, 50개의 사이트, 우선 지원."
|
"description": "기업 기능, 50명의 사용자, 50개의 사이트, 우선 지원."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "개인 사용 전용 (무료 라이센스 — 체크아웃 없음)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "결제로 진행"
|
"continueToCheckout": "결제로 진행"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "기계 클라이언트",
|
"machineClients": "기계 클라이언트",
|
||||||
"install": "설치",
|
"install": "설치",
|
||||||
"run": "실행",
|
"run": "실행",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "나중에 변경할 수 있는 클라이언트의 표시 이름입니다.",
|
"clientNameDescription": "나중에 변경할 수 있는 클라이언트의 표시 이름입니다.",
|
||||||
"clientAddress": "클라이언트 주소(고급)",
|
"clientAddress": "클라이언트 주소(고급)",
|
||||||
"setupFailedToFetchSubnet": "기본값 로드 실패",
|
"setupFailedToFetchSubnet": "기본값 로드 실패",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "인증 없음",
|
"httpDestAuthNoneTitle": "인증 없음",
|
||||||
"httpDestAuthNoneDescription": "Authorization 헤더 없이 요청을 보냅니다.",
|
"httpDestAuthNoneDescription": "Authorization 헤더 없이 요청을 보냅니다.",
|
||||||
"httpDestAuthBearerTitle": "Bearer 토큰",
|
"httpDestAuthBearerTitle": "Bearer 토큰",
|
||||||
"httpDestAuthBearerDescription": "모든 요청에 Authorization: Bearer <token> 헤더를 추가합니다.",
|
"httpDestAuthBearerDescription": "모든 요청에 Authorization: Bearer '<token>' 헤더를 추가합니다.",
|
||||||
"httpDestAuthBearerPlaceholder": "API 키 또는 토큰",
|
"httpDestAuthBearerPlaceholder": "API 키 또는 토큰",
|
||||||
"httpDestAuthBasicTitle": "기본 인증",
|
"httpDestAuthBasicTitle": "기본 인증",
|
||||||
"httpDestAuthBasicDescription": "Authorization: Basic <credentials> 헤더를 추가합니다. 자격 증명은 username:password 형식으로 제공하세요.",
|
"httpDestAuthBasicDescription": "Authorization: Basic '<credentials>' 헤더를 추가합니다. 자격 증명은 username:password 형식으로 제공하세요.",
|
||||||
"httpDestAuthBasicPlaceholder": "사용자 이름:비밀번호",
|
"httpDestAuthBasicPlaceholder": "사용자 이름:비밀번호",
|
||||||
"httpDestAuthCustomTitle": "사용자 정의 헤더",
|
"httpDestAuthCustomTitle": "사용자 정의 헤더",
|
||||||
"httpDestAuthCustomDescription": "인증을 위한 사용자 정의 HTTP 헤더 이름 및 값을 지정하세요 (예: X-API-Key).",
|
"httpDestAuthCustomDescription": "인증을 위한 사용자 정의 HTTP 헤더 이름 및 값을 지정하세요 (예: X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Foreslå nøkkel oppdatert",
|
"provisioningKeysUpdated": "Foreslå nøkkel oppdatert",
|
||||||
"provisioningKeysUpdatedDescription": "Dine endringer er lagret.",
|
"provisioningKeysUpdatedDescription": "Dine endringer er lagret.",
|
||||||
"provisioningKeysBannerTitle": "Sidens bestemmende nøkler",
|
"provisioningKeysBannerTitle": "Sidens bestemmende nøkler",
|
||||||
"provisioningKeysBannerDescription": "Generer en foreløpig nøkkel og bruk den med Nyhetskontakten for å automatisk opprette sider ved første oppstart — trenger ikke å sette opp separat innloggingsinformasjon for hver side.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Lær mer",
|
"provisioningKeysBannerButtonText": "Lær mer",
|
||||||
"pendingSitesBannerTitle": "Ventende nettsteder",
|
"pendingSitesBannerTitle": "Ventende nettsteder",
|
||||||
"pendingSitesBannerDescription": "Nettsteder som kobler deg til ved hjelp av en bestemmelsestekst, vises her for gjennomgang. Godkjenn hvert nettsted før det blir aktivt og får tilgang til ressursene dine.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Lær mer",
|
"pendingSitesBannerButtonText": "Lær mer",
|
||||||
"apiKeysSettings": "{apiKeyName} Innstillinger",
|
"apiKeysSettings": "{apiKeyName} Innstillinger",
|
||||||
"userTitle": "Administrer alle brukere",
|
"userTitle": "Administrer alle brukere",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Vennligst skriv inn et gyldig portnummer",
|
"targetErrorInvalidPortDescription": "Vennligst skriv inn et gyldig portnummer",
|
||||||
"targetErrorNoSite": "Ingen nettsted valgt",
|
"targetErrorNoSite": "Ingen nettsted valgt",
|
||||||
"targetErrorNoSiteDescription": "Velg et nettsted for målet",
|
"targetErrorNoSiteDescription": "Velg et nettsted for målet",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Mål opprettet",
|
"targetCreated": "Mål opprettet",
|
||||||
"targetCreatedDescription": "Målet har blitt opprettet",
|
"targetCreatedDescription": "Målet har blitt opprettet",
|
||||||
"targetErrorCreate": "Kunne ikke opprette målet",
|
"targetErrorCreate": "Kunne ikke opprette målet",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Enterprise features, 50 brukere, 50 nettsteder og prioritetsstøtte."
|
"description": "Enterprise features, 50 brukere, 50 nettsteder og prioritetsstøtte."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Kun personlig bruk (gratis lisens - ingen utsjekking)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Fortsett til kassen"
|
"continueToCheckout": "Fortsett til kassen"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Maskinklienter",
|
"machineClients": "Maskinklienter",
|
||||||
"install": "Installer",
|
"install": "Installer",
|
||||||
"run": "Kjør",
|
"run": "Kjør",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "Visningsnavnet til klienten som kan endres senere.",
|
"clientNameDescription": "Visningsnavnet til klienten som kan endres senere.",
|
||||||
"clientAddress": "Klientadresse (avansert)",
|
"clientAddress": "Klientadresse (avansert)",
|
||||||
"setupFailedToFetchSubnet": "Kunne ikke hente standard undernett",
|
"setupFailedToFetchSubnet": "Kunne ikke hente standard undernett",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Ingen godkjenning",
|
"httpDestAuthNoneTitle": "Ingen godkjenning",
|
||||||
"httpDestAuthNoneDescription": "Sender forespørsler uten autorisasjonsoverskrift.",
|
"httpDestAuthNoneDescription": "Sender forespørsler uten autorisasjonsoverskrift.",
|
||||||
"httpDestAuthBearerTitle": "Bærer Symbol",
|
"httpDestAuthBearerTitle": "Bærer Symbol",
|
||||||
"httpDestAuthBearerDescription": "Legger til en autorisasjon: Bearer <token> header til hver forespørsel.",
|
"httpDestAuthBearerDescription": "Legger til en autorisasjon: Bearer '<token>' header til hver forespørsel.",
|
||||||
"httpDestAuthBearerPlaceholder": "Din API-nøkkel eller token",
|
"httpDestAuthBearerPlaceholder": "Din API-nøkkel eller token",
|
||||||
"httpDestAuthBasicTitle": "Standard Auth",
|
"httpDestAuthBasicTitle": "Standard Auth",
|
||||||
"httpDestAuthBasicDescription": "Legger til en godkjenning: Grunnleggende <credentials> overskrift. Angi legitimasjon som brukernavn:passord.",
|
"httpDestAuthBasicDescription": "Legger til en godkjenning: Grunnleggende '<credentials>' overskrift. Angi legitimasjon som brukernavn:passord.",
|
||||||
"httpDestAuthBasicPlaceholder": "brukernavn:passord",
|
"httpDestAuthBasicPlaceholder": "brukernavn:passord",
|
||||||
"httpDestAuthCustomTitle": "Egendefinert topptekst",
|
"httpDestAuthCustomTitle": "Egendefinert topptekst",
|
||||||
"httpDestAuthCustomDescription": "Angi et egendefinert HTTP headers navn og verdi for autentisering (f.eks X-API-Key).",
|
"httpDestAuthCustomDescription": "Angi et egendefinert HTTP headers navn og verdi for autentisering (f.eks X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Provisie sleutel bijgewerkt",
|
"provisioningKeysUpdated": "Provisie sleutel bijgewerkt",
|
||||||
"provisioningKeysUpdatedDescription": "Uw wijzigingen zijn opgeslagen.",
|
"provisioningKeysUpdatedDescription": "Uw wijzigingen zijn opgeslagen.",
|
||||||
"provisioningKeysBannerTitle": "Bewerkingssleutels voor websites",
|
"provisioningKeysBannerTitle": "Bewerkingssleutels voor websites",
|
||||||
"provisioningKeysBannerDescription": "Genereer een provisioning-sleutel en gebruik deze met de Newt-connector om automatisch sites aan te maken bij het opstarten van de eerste opstart- het is niet nodig om afzonderlijke inloggegevens in te stellen voor elke site.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Meer informatie",
|
"provisioningKeysBannerButtonText": "Meer informatie",
|
||||||
"pendingSitesBannerTitle": "Openstaande sites",
|
"pendingSitesBannerTitle": "Openstaande sites",
|
||||||
"pendingSitesBannerDescription": "Sites die met elkaar verbinden met behulp van een provisioning-sleutel verschijnen hier voor beoordeling. Accepteer elke site voordat deze actief wordt en krijgt toegang tot uw bronnen.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Meer informatie",
|
"pendingSitesBannerButtonText": "Meer informatie",
|
||||||
"apiKeysSettings": "{apiKeyName} instellingen",
|
"apiKeysSettings": "{apiKeyName} instellingen",
|
||||||
"userTitle": "Alle gebruikers beheren",
|
"userTitle": "Alle gebruikers beheren",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Voer een geldig poortnummer in",
|
"targetErrorInvalidPortDescription": "Voer een geldig poortnummer in",
|
||||||
"targetErrorNoSite": "Geen site geselecteerd",
|
"targetErrorNoSite": "Geen site geselecteerd",
|
||||||
"targetErrorNoSiteDescription": "Selecteer een site voor het doel",
|
"targetErrorNoSiteDescription": "Selecteer een site voor het doel",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Doel aangemaakt",
|
"targetCreated": "Doel aangemaakt",
|
||||||
"targetCreatedDescription": "Doel is succesvol aangemaakt",
|
"targetCreatedDescription": "Doel is succesvol aangemaakt",
|
||||||
"targetErrorCreate": "Kan doel niet aanmaken",
|
"targetErrorCreate": "Kan doel niet aanmaken",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Enterprise functies, 50 gebruikers, 50 sites en prioriteit ondersteuning."
|
"description": "Enterprise functies, 50 gebruikers, 50 sites en prioriteit ondersteuning."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Alleen persoonlijk gebruik (gratis licentie - geen afrekenen)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Doorgaan naar afrekenen"
|
"continueToCheckout": "Doorgaan naar afrekenen"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Machine Clienten",
|
"machineClients": "Machine Clienten",
|
||||||
"install": "Installeren",
|
"install": "Installeren",
|
||||||
"run": "Uitvoeren",
|
"run": "Uitvoeren",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "De weergavenaam van de client die later gewijzigd kan worden.",
|
"clientNameDescription": "De weergavenaam van de client die later gewijzigd kan worden.",
|
||||||
"clientAddress": "Klant adres (Geavanceerd)",
|
"clientAddress": "Klant adres (Geavanceerd)",
|
||||||
"setupFailedToFetchSubnet": "Kan standaard subnet niet ophalen",
|
"setupFailedToFetchSubnet": "Kan standaard subnet niet ophalen",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Geen authenticatie",
|
"httpDestAuthNoneTitle": "Geen authenticatie",
|
||||||
"httpDestAuthNoneDescription": "Stuurt verzoeken zonder toestemmingskop.",
|
"httpDestAuthNoneDescription": "Stuurt verzoeken zonder toestemmingskop.",
|
||||||
"httpDestAuthBearerTitle": "Betere Token",
|
"httpDestAuthBearerTitle": "Betere Token",
|
||||||
"httpDestAuthBearerDescription": "Voegt een machtiging toe: Drager <token> header aan elke aanvraag.",
|
"httpDestAuthBearerDescription": "Voegt een machtiging toe: Drager '<token>' header aan elke aanvraag.",
|
||||||
"httpDestAuthBearerPlaceholder": "Uw API-sleutel of -token",
|
"httpDestAuthBearerPlaceholder": "Uw API-sleutel of -token",
|
||||||
"httpDestAuthBasicTitle": "Basis authenticatie",
|
"httpDestAuthBasicTitle": "Basis authenticatie",
|
||||||
"httpDestAuthBasicDescription": "Voegt een Authorizatie toe: Basis <credentials> kop. Geef inloggegevens op als gebruikersnaam:wachtwoord.",
|
"httpDestAuthBasicDescription": "Voegt een Authorizatie toe: Basis '<credentials>' kop. Geef inloggegevens op als gebruikersnaam:wachtwoord.",
|
||||||
"httpDestAuthBasicPlaceholder": "Gebruikersnaam:wachtwoord",
|
"httpDestAuthBasicPlaceholder": "Gebruikersnaam:wachtwoord",
|
||||||
"httpDestAuthCustomTitle": "Aangepaste koptekst",
|
"httpDestAuthCustomTitle": "Aangepaste koptekst",
|
||||||
"httpDestAuthCustomDescription": "Specificeer een aangepaste HTTP header naam en waarde voor authenticatie (bijv. X-API-Key).",
|
"httpDestAuthCustomDescription": "Specificeer een aangepaste HTTP header naam en waarde voor authenticatie (bijv. X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Klucz zaopatrzenia zaktualizowany",
|
"provisioningKeysUpdated": "Klucz zaopatrzenia zaktualizowany",
|
||||||
"provisioningKeysUpdatedDescription": "Twoje zmiany zostały zapisane.",
|
"provisioningKeysUpdatedDescription": "Twoje zmiany zostały zapisane.",
|
||||||
"provisioningKeysBannerTitle": "Klucze Zaopatrzenia witryny",
|
"provisioningKeysBannerTitle": "Klucze Zaopatrzenia witryny",
|
||||||
"provisioningKeysBannerDescription": "Wygeneruj klucz tworzenia rezerw i użyj go z konektorem Newt do automatycznego tworzenia witryn przy pierwszym uruchomieniu — nie ma potrzeby ustawiania oddzielnych poświadczeń dla każdej witryny.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Dowiedz się więcej",
|
"provisioningKeysBannerButtonText": "Dowiedz się więcej",
|
||||||
"pendingSitesBannerTitle": "Witryny oczekujące",
|
"pendingSitesBannerTitle": "Witryny oczekujące",
|
||||||
"pendingSitesBannerDescription": "Witryny, które łączą się przy użyciu klucza zaopatrzenia, pojawiają się tutaj, aby przejrzeć. Zatwierdź każdą witrynę, zanim stanie się aktywna i uzyska dostęp do twoich zasobów.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Dowiedz się więcej",
|
"pendingSitesBannerButtonText": "Dowiedz się więcej",
|
||||||
"apiKeysSettings": "Ustawienia {apiKeyName}",
|
"apiKeysSettings": "Ustawienia {apiKeyName}",
|
||||||
"userTitle": "Zarządzaj wszystkimi użytkownikami",
|
"userTitle": "Zarządzaj wszystkimi użytkownikami",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Wprowadź prawidłowy numer portu",
|
"targetErrorInvalidPortDescription": "Wprowadź prawidłowy numer portu",
|
||||||
"targetErrorNoSite": "Nie wybrano witryny",
|
"targetErrorNoSite": "Nie wybrano witryny",
|
||||||
"targetErrorNoSiteDescription": "Wybierz witrynę docelową",
|
"targetErrorNoSiteDescription": "Wybierz witrynę docelową",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Cel utworzony",
|
"targetCreated": "Cel utworzony",
|
||||||
"targetCreatedDescription": "Cel został utworzony pomyślnie",
|
"targetCreatedDescription": "Cel został utworzony pomyślnie",
|
||||||
"targetErrorCreate": "Nie udało się utworzyć celu",
|
"targetErrorCreate": "Nie udało się utworzyć celu",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Cechy przedsiębiorstw, 50 użytkowników, 50 obiektów i wsparcie priorytetowe."
|
"description": "Cechy przedsiębiorstw, 50 użytkowników, 50 obiektów i wsparcie priorytetowe."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Wyłącznie do użytku osobistego (bezpłatna licencja – brak zamówień)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Przejdź do zamówienia"
|
"continueToCheckout": "Przejdź do zamówienia"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Klienci maszyn",
|
"machineClients": "Klienci maszyn",
|
||||||
"install": "Zainstaluj",
|
"install": "Zainstaluj",
|
||||||
"run": "Uruchom",
|
"run": "Uruchom",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "Wyświetlana nazwa klienta, która może zostać zmieniona później.",
|
"clientNameDescription": "Wyświetlana nazwa klienta, która może zostać zmieniona później.",
|
||||||
"clientAddress": "Adres klienta (Zaawansowany)",
|
"clientAddress": "Adres klienta (Zaawansowany)",
|
||||||
"setupFailedToFetchSubnet": "Nie udało się pobrać domyślnej podsieci",
|
"setupFailedToFetchSubnet": "Nie udało się pobrać domyślnej podsieci",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Brak uwierzytelniania",
|
"httpDestAuthNoneTitle": "Brak uwierzytelniania",
|
||||||
"httpDestAuthNoneDescription": "Wysyła żądania bez nagłówka autoryzacji.",
|
"httpDestAuthNoneDescription": "Wysyła żądania bez nagłówka autoryzacji.",
|
||||||
"httpDestAuthBearerTitle": "Token Bearer",
|
"httpDestAuthBearerTitle": "Token Bearer",
|
||||||
"httpDestAuthBearerDescription": "Dodaje autoryzację: nagłówek Bearer <token> do każdego żądania.",
|
"httpDestAuthBearerDescription": "Dodaje autoryzację: nagłówek Bearer '<token>' do każdego żądania.",
|
||||||
"httpDestAuthBearerPlaceholder": "Twój klucz API lub token",
|
"httpDestAuthBearerPlaceholder": "Twój klucz API lub token",
|
||||||
"httpDestAuthBasicTitle": "Podstawowa Autoryzacja",
|
"httpDestAuthBasicTitle": "Podstawowa Autoryzacja",
|
||||||
"httpDestAuthBasicDescription": "Dodaje Autoryzacja: Nagłówek Basic <credentials> . Podaj poświadczenia jako nazwę użytkownika: hasło.",
|
"httpDestAuthBasicDescription": "Dodaje Autoryzacja: Nagłówek Basic '<credentials>' . Podaj poświadczenia jako nazwę użytkownika: hasło.",
|
||||||
"httpDestAuthBasicPlaceholder": "Nazwa użytkownika:hasło",
|
"httpDestAuthBasicPlaceholder": "Nazwa użytkownika:hasło",
|
||||||
"httpDestAuthCustomTitle": "Niestandardowy nagłówek",
|
"httpDestAuthCustomTitle": "Niestandardowy nagłówek",
|
||||||
"httpDestAuthCustomDescription": "Określ niestandardową nazwę nagłówka HTTP i wartość dla uwierzytelniania (np. X-API-Key).",
|
"httpDestAuthCustomDescription": "Określ niestandardową nazwę nagłówka HTTP i wartość dla uwierzytelniania (np. X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Chave de provisionamento atualizada",
|
"provisioningKeysUpdated": "Chave de provisionamento atualizada",
|
||||||
"provisioningKeysUpdatedDescription": "Suas alterações foram salvas.",
|
"provisioningKeysUpdatedDescription": "Suas alterações foram salvas.",
|
||||||
"provisioningKeysBannerTitle": "Chaves de provisionamento do site",
|
"provisioningKeysBannerTitle": "Chaves de provisionamento do site",
|
||||||
"provisioningKeysBannerDescription": "Gerar uma chave de provisionamento e usá-la com o conector de Newt para criar automaticamente sites na primeira inicialização — não é necessário configurar credenciais separadas para cada site.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Saiba mais",
|
"provisioningKeysBannerButtonText": "Saiba mais",
|
||||||
"pendingSitesBannerTitle": "Sites pendentes",
|
"pendingSitesBannerTitle": "Sites pendentes",
|
||||||
"pendingSitesBannerDescription": "Sites que conectam usando uma chave de provisionamento aparecem aqui para revisão. Aprovar cada site antes de se tornar ativo e ganhar acesso a seus recursos.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Saiba mais",
|
"pendingSitesBannerButtonText": "Saiba mais",
|
||||||
"apiKeysSettings": "Configurações de {apiKeyName}",
|
"apiKeysSettings": "Configurações de {apiKeyName}",
|
||||||
"userTitle": "Gerir Todos os Utilizadores",
|
"userTitle": "Gerir Todos os Utilizadores",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Por favor, digite um número de porta válido",
|
"targetErrorInvalidPortDescription": "Por favor, digite um número de porta válido",
|
||||||
"targetErrorNoSite": "Nenhum site selecionado",
|
"targetErrorNoSite": "Nenhum site selecionado",
|
||||||
"targetErrorNoSiteDescription": "Selecione um site para o destino",
|
"targetErrorNoSiteDescription": "Selecione um site para o destino",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Destino criado",
|
"targetCreated": "Destino criado",
|
||||||
"targetCreatedDescription": "O alvo foi criado com sucesso",
|
"targetCreatedDescription": "O alvo foi criado com sucesso",
|
||||||
"targetErrorCreate": "Falha ao criar destino",
|
"targetErrorCreate": "Falha ao criar destino",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Recursos de empresa, 50 usuários, 50 sites e apoio prioritário."
|
"description": "Recursos de empresa, 50 usuários, 50 sites e apoio prioritário."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Apenas uso pessoal (licença gratuita — sem check-out)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Continuar com checkout"
|
"continueToCheckout": "Continuar com checkout"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Clientes de máquina",
|
"machineClients": "Clientes de máquina",
|
||||||
"install": "Instale",
|
"install": "Instale",
|
||||||
"run": "Executar",
|
"run": "Executar",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "O nome de exibição do cliente que pode ser alterado mais tarde.",
|
"clientNameDescription": "O nome de exibição do cliente que pode ser alterado mais tarde.",
|
||||||
"clientAddress": "Endereço do Cliente (Avançado)",
|
"clientAddress": "Endereço do Cliente (Avançado)",
|
||||||
"setupFailedToFetchSubnet": "Falha ao buscar a subrede padrão",
|
"setupFailedToFetchSubnet": "Falha ao buscar a subrede padrão",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Sem Autenticação",
|
"httpDestAuthNoneTitle": "Sem Autenticação",
|
||||||
"httpDestAuthNoneDescription": "Envia pedidos sem um cabeçalho de autorização.",
|
"httpDestAuthNoneDescription": "Envia pedidos sem um cabeçalho de autorização.",
|
||||||
"httpDestAuthBearerTitle": "Token do portador",
|
"httpDestAuthBearerTitle": "Token do portador",
|
||||||
"httpDestAuthBearerDescription": "Adiciona uma autorização: Bearer <token> header a cada requisição.",
|
"httpDestAuthBearerDescription": "Adiciona uma autorização: Bearer '<token>' header a cada requisição.",
|
||||||
"httpDestAuthBearerPlaceholder": "Sua chave de API ou token",
|
"httpDestAuthBearerPlaceholder": "Sua chave de API ou token",
|
||||||
"httpDestAuthBasicTitle": "Autenticação básica",
|
"httpDestAuthBasicTitle": "Autenticação básica",
|
||||||
"httpDestAuthBasicDescription": "Adiciona uma Autorização: cabeçalho <credentials> básico. Forneça credenciais como nome de usuário:senha.",
|
"httpDestAuthBasicDescription": "Adiciona uma Autorização: cabeçalho '<credentials>' básico. Forneça credenciais como nome de usuário:senha.",
|
||||||
"httpDestAuthBasicPlaceholder": "Usuário:password",
|
"httpDestAuthBasicPlaceholder": "Usuário:password",
|
||||||
"httpDestAuthCustomTitle": "Cabeçalho personalizado",
|
"httpDestAuthCustomTitle": "Cabeçalho personalizado",
|
||||||
"httpDestAuthCustomDescription": "Especifique um nome e valor de cabeçalho HTTP personalizado para autenticação (por exemplo, X-API-Key).",
|
"httpDestAuthCustomDescription": "Especifique um nome e valor de cabeçalho HTTP personalizado para autenticação (por exemplo, X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Ключ подготовки обновлен",
|
"provisioningKeysUpdated": "Ключ подготовки обновлен",
|
||||||
"provisioningKeysUpdatedDescription": "Ваши изменения были сохранены.",
|
"provisioningKeysUpdatedDescription": "Ваши изменения были сохранены.",
|
||||||
"provisioningKeysBannerTitle": "Ключи подготовки сайта",
|
"provisioningKeysBannerTitle": "Ключи подготовки сайта",
|
||||||
"provisioningKeysBannerDescription": "Генерировать подготовительный ключ и использовать его вместе с Новым коннектором для автоматического создания сайтов при первом запуске — нет необходимости настраивать отдельные учетные данные для каждого сайта.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Узнать больше",
|
"provisioningKeysBannerButtonText": "Узнать больше",
|
||||||
"pendingSitesBannerTitle": "Ожидающие сайты",
|
"pendingSitesBannerTitle": "Ожидающие сайты",
|
||||||
"pendingSitesBannerDescription": "Сайты, связанные с использованием ключа подготовки, появляются здесь для проверки. Одобрите каждый сайт, прежде чем он станет активным и получит доступ к вашим ресурсам.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Узнать больше",
|
"pendingSitesBannerButtonText": "Узнать больше",
|
||||||
"apiKeysSettings": "Настройки {apiKeyName}",
|
"apiKeysSettings": "Настройки {apiKeyName}",
|
||||||
"userTitle": "Управление всеми пользователями",
|
"userTitle": "Управление всеми пользователями",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Пожалуйста, введите правильный номер порта",
|
"targetErrorInvalidPortDescription": "Пожалуйста, введите правильный номер порта",
|
||||||
"targetErrorNoSite": "Сайт не выбран",
|
"targetErrorNoSite": "Сайт не выбран",
|
||||||
"targetErrorNoSiteDescription": "Пожалуйста, выберите сайт для цели",
|
"targetErrorNoSiteDescription": "Пожалуйста, выберите сайт для цели",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Цель создана",
|
"targetCreated": "Цель создана",
|
||||||
"targetCreatedDescription": "Цель была успешно создана",
|
"targetCreatedDescription": "Цель была успешно создана",
|
||||||
"targetErrorCreate": "Не удалось создать цель",
|
"targetErrorCreate": "Не удалось создать цель",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Функции предприятия, 50 пользователей, 50 сайтов, а также приоритетная поддержка."
|
"description": "Функции предприятия, 50 пользователей, 50 сайтов, а также приоритетная поддержка."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Только для личного пользования (бесплатная лицензия — без оформления)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Продолжить оформление заказа"
|
"continueToCheckout": "Продолжить оформление заказа"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Машинные клиенты",
|
"machineClients": "Машинные клиенты",
|
||||||
"install": "Установить",
|
"install": "Установить",
|
||||||
"run": "Запустить",
|
"run": "Запустить",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "Отображаемое имя клиента, которое может быть изменено позже.",
|
"clientNameDescription": "Отображаемое имя клиента, которое может быть изменено позже.",
|
||||||
"clientAddress": "Адрес клиента (Дополнительно)",
|
"clientAddress": "Адрес клиента (Дополнительно)",
|
||||||
"setupFailedToFetchSubnet": "Не удалось получить подсеть по умолчанию",
|
"setupFailedToFetchSubnet": "Не удалось получить подсеть по умолчанию",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Нет аутентификации",
|
"httpDestAuthNoneTitle": "Нет аутентификации",
|
||||||
"httpDestAuthNoneDescription": "Отправляет запросы без заголовка авторизации.",
|
"httpDestAuthNoneDescription": "Отправляет запросы без заголовка авторизации.",
|
||||||
"httpDestAuthBearerTitle": "Жетон носителя",
|
"httpDestAuthBearerTitle": "Жетон носителя",
|
||||||
"httpDestAuthBearerDescription": "Добавляет заголовок Authorization: Bearer <token> к каждому запросу.",
|
"httpDestAuthBearerDescription": "Добавляет заголовок Authorization: Bearer '<token>' к каждому запросу.",
|
||||||
"httpDestAuthBearerPlaceholder": "Ваш ключ API или токен",
|
"httpDestAuthBearerPlaceholder": "Ваш ключ API или токен",
|
||||||
"httpDestAuthBasicTitle": "Базовая авторизация",
|
"httpDestAuthBasicTitle": "Базовая авторизация",
|
||||||
"httpDestAuthBasicDescription": "Добавляет Authorization: Basic <credentials> header. Предоставьте учетные данные в качестве имени пользователя:password.",
|
"httpDestAuthBasicDescription": "Добавляет Authorization: Basic '<credentials>' header. Предоставьте учетные данные в качестве имени пользователя:password.",
|
||||||
"httpDestAuthBasicPlaceholder": "имя пользователя:пароль",
|
"httpDestAuthBasicPlaceholder": "имя пользователя:пароль",
|
||||||
"httpDestAuthCustomTitle": "Пользовательский заголовок",
|
"httpDestAuthCustomTitle": "Пользовательский заголовок",
|
||||||
"httpDestAuthCustomDescription": "Укажите пользовательское имя заголовка HTTP и значение для аутентификации (например, X-API-Key).",
|
"httpDestAuthCustomDescription": "Укажите пользовательское имя заголовка HTTP и значение для аутентификации (например, X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "Tedarik anahtarı güncellendi",
|
"provisioningKeysUpdated": "Tedarik anahtarı güncellendi",
|
||||||
"provisioningKeysUpdatedDescription": "Değişiklikleriniz kaydedildi.",
|
"provisioningKeysUpdatedDescription": "Değişiklikleriniz kaydedildi.",
|
||||||
"provisioningKeysBannerTitle": "Site Tedarik Anahtarları",
|
"provisioningKeysBannerTitle": "Site Tedarik Anahtarları",
|
||||||
"provisioningKeysBannerDescription": "Tedarik anahtarı oluşturun ve ilk başlangıçta siteleri otomatik olarak oluşturmak için Newt konektörüyle kullanın — her site için ayrı kimlik bilgileri ayarlamaya gerek yoktur.",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "Daha fazla bilgi",
|
"provisioningKeysBannerButtonText": "Daha fazla bilgi",
|
||||||
"pendingSitesBannerTitle": "Bekleyen Siteler",
|
"pendingSitesBannerTitle": "Bekleyen Siteler",
|
||||||
"pendingSitesBannerDescription": "Tedarik anahtarı kullanarak bağlanan siteler burada incelenmek için görünür. Aktif hale gelmeden ve kaynaklarınıza erişim kazanmadan önce her siteyi onaylayın.",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "Daha fazla bilgi",
|
"pendingSitesBannerButtonText": "Daha fazla bilgi",
|
||||||
"apiKeysSettings": "{apiKeyName} Ayarları",
|
"apiKeysSettings": "{apiKeyName} Ayarları",
|
||||||
"userTitle": "Tüm Kullanıcıları Yönet",
|
"userTitle": "Tüm Kullanıcıları Yönet",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "Lütfen geçerli bir port numarası girin",
|
"targetErrorInvalidPortDescription": "Lütfen geçerli bir port numarası girin",
|
||||||
"targetErrorNoSite": "Hiçbir site seçili değil",
|
"targetErrorNoSite": "Hiçbir site seçili değil",
|
||||||
"targetErrorNoSiteDescription": "Lütfen hedef için bir site seçin",
|
"targetErrorNoSiteDescription": "Lütfen hedef için bir site seçin",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "Hedef oluşturuldu",
|
"targetCreated": "Hedef oluşturuldu",
|
||||||
"targetCreatedDescription": "Hedef başarıyla oluşturuldu",
|
"targetCreatedDescription": "Hedef başarıyla oluşturuldu",
|
||||||
"targetErrorCreate": "Hedef oluşturma başarısız oldu",
|
"targetErrorCreate": "Hedef oluşturma başarısız oldu",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "Kurumsal özellikler, 50 kullanıcı, 50 site ve öncelikli destek."
|
"description": "Kurumsal özellikler, 50 kullanıcı, 50 site ve öncelikli destek."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "Yalnızca kişisel kullanım (ücretsiz lisans — ödeme yapılmaz)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "Ödemeye Devam Et"
|
"continueToCheckout": "Ödemeye Devam Et"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "Makine İstemcileri",
|
"machineClients": "Makine İstemcileri",
|
||||||
"install": "Yükle",
|
"install": "Yükle",
|
||||||
"run": "Çalıştır",
|
"run": "Çalıştır",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "Daha sonra değiştirilebilecek istemcinin görünen adı.",
|
"clientNameDescription": "Daha sonra değiştirilebilecek istemcinin görünen adı.",
|
||||||
"clientAddress": "İstemci Adresi (Gelişmiş)",
|
"clientAddress": "İstemci Adresi (Gelişmiş)",
|
||||||
"setupFailedToFetchSubnet": "Varsayılan alt ağ alınamadı",
|
"setupFailedToFetchSubnet": "Varsayılan alt ağ alınamadı",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "Kimlik Doğrulama Yok",
|
"httpDestAuthNoneTitle": "Kimlik Doğrulama Yok",
|
||||||
"httpDestAuthNoneDescription": "Yetkilendirme başlığı olmadan istekler gönderir.",
|
"httpDestAuthNoneDescription": "Yetkilendirme başlığı olmadan istekler gönderir.",
|
||||||
"httpDestAuthBearerTitle": "Taşıyıcı Jetonu",
|
"httpDestAuthBearerTitle": "Taşıyıcı Jetonu",
|
||||||
"httpDestAuthBearerDescription": "Her isteğe bir Yetkilendirme: Taşıyıcı <token> başlığı ekler.",
|
"httpDestAuthBearerDescription": "Her isteğe bir Yetkilendirme: Taşıyıcı '<token>' başlığı ekler.",
|
||||||
"httpDestAuthBearerPlaceholder": "API anahtarınız veya jetonunuz",
|
"httpDestAuthBearerPlaceholder": "API anahtarınız veya jetonunuz",
|
||||||
"httpDestAuthBasicTitle": "Temel Kimlik Doğrulama",
|
"httpDestAuthBasicTitle": "Temel Kimlik Doğrulama",
|
||||||
"httpDestAuthBasicDescription": "Authorization: Temel <belirtecikler> başlığı ekler. Yetkilendirmeleri kullanıcı adı:şifre olarak sağlayın.",
|
"httpDestAuthBasicDescription": "Authorization: Temel '<belirtecikler>' başlığı ekler. Yetkilendirmeleri kullanıcı adı:şifre olarak sağlayın.",
|
||||||
"httpDestAuthBasicPlaceholder": "kullanıcı adı:şifre",
|
"httpDestAuthBasicPlaceholder": "kullanıcı adı:şifre",
|
||||||
"httpDestAuthCustomTitle": "Özel Başlık",
|
"httpDestAuthCustomTitle": "Özel Başlık",
|
||||||
"httpDestAuthCustomDescription": "Kimlik doğrulama için özel bir HTTP başlık adı ve değer belirtin (örn. X-API-Key).",
|
"httpDestAuthCustomDescription": "Kimlik doğrulama için özel bir HTTP başlık adı ve değer belirtin (örn. X-API-Key).",
|
||||||
|
|||||||
@@ -371,10 +371,10 @@
|
|||||||
"provisioningKeysUpdated": "置备密钥已更新",
|
"provisioningKeysUpdated": "置备密钥已更新",
|
||||||
"provisioningKeysUpdatedDescription": "您的更改已保存。",
|
"provisioningKeysUpdatedDescription": "您的更改已保存。",
|
||||||
"provisioningKeysBannerTitle": "站点置备密钥",
|
"provisioningKeysBannerTitle": "站点置备密钥",
|
||||||
"provisioningKeysBannerDescription": "生成一个预配键并使用它来在首次启动时自动创建站点——无需为每个站点设置单独的凭证。",
|
"provisioningKeysBannerDescription": "Generate a provisioning key and use it with the Newt connector to automatically create sites on first startup - no need to set up separate credentials for each site.",
|
||||||
"provisioningKeysBannerButtonText": "了解更多",
|
"provisioningKeysBannerButtonText": "了解更多",
|
||||||
"pendingSitesBannerTitle": "待定站点",
|
"pendingSitesBannerTitle": "待定站点",
|
||||||
"pendingSitesBannerDescription": "使用预配键连接的站点会出现在这里供审核。在站点开始运行之前批准并获取对您资源的访问权限。",
|
"pendingSitesBannerDescription": "Sites that connect using a provisioning key appear here for review.",
|
||||||
"pendingSitesBannerButtonText": "了解更多",
|
"pendingSitesBannerButtonText": "了解更多",
|
||||||
"apiKeysSettings": "{apiKeyName} 设置",
|
"apiKeysSettings": "{apiKeyName} 设置",
|
||||||
"userTitle": "管理所有用户",
|
"userTitle": "管理所有用户",
|
||||||
@@ -624,6 +624,8 @@
|
|||||||
"targetErrorInvalidPortDescription": "请输入有效的端口号",
|
"targetErrorInvalidPortDescription": "请输入有效的端口号",
|
||||||
"targetErrorNoSite": "没有选择站点",
|
"targetErrorNoSite": "没有选择站点",
|
||||||
"targetErrorNoSiteDescription": "请选择目标站点",
|
"targetErrorNoSiteDescription": "请选择目标站点",
|
||||||
|
"targetTargetsCleared": "Targets cleared",
|
||||||
|
"targetTargetsClearedDescription": "All targets have been removed from this resource",
|
||||||
"targetCreated": "目标已创建",
|
"targetCreated": "目标已创建",
|
||||||
"targetCreatedDescription": "目标已成功创建",
|
"targetCreatedDescription": "目标已成功创建",
|
||||||
"targetErrorCreate": "创建目标失败",
|
"targetErrorCreate": "创建目标失败",
|
||||||
@@ -2346,7 +2348,7 @@
|
|||||||
"description": "企业特征、50个用户、50个站点和优先支持。"
|
"description": "企业特征、50个用户、50个站点和优先支持。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"personalUseOnly": "仅供个人使用 (免费许可证-无签出)",
|
"personalUseOnly": "Personal use only (free license - no checkout)",
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"continueToCheckout": "继续签出"
|
"continueToCheckout": "继续签出"
|
||||||
},
|
},
|
||||||
@@ -2607,6 +2609,9 @@
|
|||||||
"machineClients": "机器客户端",
|
"machineClients": "机器客户端",
|
||||||
"install": "安装",
|
"install": "安装",
|
||||||
"run": "运行",
|
"run": "运行",
|
||||||
|
"envFile": "Environment File",
|
||||||
|
"serviceFile": "Service File",
|
||||||
|
"enableAndStart": "Enable and Start",
|
||||||
"clientNameDescription": "可以稍后更改的客户端的显示名称。",
|
"clientNameDescription": "可以稍后更改的客户端的显示名称。",
|
||||||
"clientAddress": "客户端地址 (高级)",
|
"clientAddress": "客户端地址 (高级)",
|
||||||
"setupFailedToFetchSubnet": "获取默认子网失败",
|
"setupFailedToFetchSubnet": "获取默认子网失败",
|
||||||
@@ -2845,10 +2850,10 @@
|
|||||||
"httpDestAuthNoneTitle": "无身份验证",
|
"httpDestAuthNoneTitle": "无身份验证",
|
||||||
"httpDestAuthNoneDescription": "在没有授权头的情况下发送请求。",
|
"httpDestAuthNoneDescription": "在没有授权头的情况下发送请求。",
|
||||||
"httpDestAuthBearerTitle": "持有者令牌",
|
"httpDestAuthBearerTitle": "持有者令牌",
|
||||||
"httpDestAuthBearerDescription": "添加授权:每个请求的标题为 <token>。",
|
"httpDestAuthBearerDescription": "添加授权:每个请求的标题为 '<token>'。",
|
||||||
"httpDestAuthBearerPlaceholder": "您的 API 密钥或令牌",
|
"httpDestAuthBearerPlaceholder": "您的 API 密钥或令牌",
|
||||||
"httpDestAuthBasicTitle": "基本认证",
|
"httpDestAuthBasicTitle": "基本认证",
|
||||||
"httpDestAuthBasicDescription": "添加授权:基本 <credentials> 头。提供用户名:密码的凭据。",
|
"httpDestAuthBasicDescription": "添加授权:基本 '<credentials>' 头。提供用户名:密码的凭据。",
|
||||||
"httpDestAuthBasicPlaceholder": "用户名:密码",
|
"httpDestAuthBasicPlaceholder": "用户名:密码",
|
||||||
"httpDestAuthCustomTitle": "自定义标题",
|
"httpDestAuthCustomTitle": "自定义标题",
|
||||||
"httpDestAuthCustomDescription": "指定自定义 HTTP 头名称和身份验证值 (例如,X-API 键)。",
|
"httpDestAuthCustomDescription": "指定自定义 HTTP 头名称和身份验证值 (例如,X-API 键)。",
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export class LogStreamingManager {
|
|||||||
start(): void {
|
start(): void {
|
||||||
if (this.isRunning) return;
|
if (this.isRunning) return;
|
||||||
this.isRunning = true;
|
this.isRunning = true;
|
||||||
logger.info("LogStreamingManager: started");
|
logger.debug("LogStreamingManager: started");
|
||||||
this.schedulePoll(POLL_INTERVAL_MS);
|
this.schedulePoll(POLL_INTERVAL_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -171,9 +171,8 @@ export async function flushSiteBandwidthToDb(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL: batch UPDATE … FROM (VALUES …) — single round-trip per chunk.
|
// PostgreSQL: batch UPDATE … FROM (VALUES …) — single round-trip per chunk.
|
||||||
const valuesList = chunk.map(
|
const valuesList = chunk.map(([publicKey, { bytesIn, bytesOut }]) =>
|
||||||
([publicKey, { bytesIn, bytesOut }]) =>
|
sql`(${publicKey}::text, ${bytesIn}::real, ${bytesOut}::real)`
|
||||||
sql`(${publicKey}, ${bytesIn}, ${bytesOut})`
|
|
||||||
);
|
);
|
||||||
const valuesClause = sql.join(valuesList, sql`, `);
|
const valuesClause = sql.join(valuesList, sql`, `);
|
||||||
return dbQueryRows<{ orgId: string; pubKey: string }>(sql`
|
return dbQueryRows<{ orgId: string; pubKey: string }>(sql`
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { sendToExitNode } from "#dynamic/lib/exitNodes";
|
|||||||
import { buildClientConfigurationForNewtClient } from "./buildConfiguration";
|
import { buildClientConfigurationForNewtClient } from "./buildConfiguration";
|
||||||
import { convertTargetsIfNessicary } from "../client/targets";
|
import { convertTargetsIfNessicary } from "../client/targets";
|
||||||
import { canCompress } from "@server/lib/clientVersionChecks";
|
import { canCompress } from "@server/lib/clientVersionChecks";
|
||||||
|
import config from "@server/lib/config";
|
||||||
|
|
||||||
export const handleGetConfigMessage: MessageHandler = async (context) => {
|
export const handleGetConfigMessage: MessageHandler = async (context) => {
|
||||||
const { message, client, sendToClient } = context;
|
const { message, client, sendToClient } = context;
|
||||||
@@ -55,7 +56,7 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
|
|||||||
|
|
||||||
if (existingSite.lastHolePunch && now - existingSite.lastHolePunch > 5) {
|
if (existingSite.lastHolePunch && now - existingSite.lastHolePunch > 5) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`handleGetConfigMessage: Site ${existingSite.siteId} last hole punch is too old, skipping`
|
`Site last hole punch is too old; skipping this register. The site is failing to hole punch and identify its network address with the server. Can the client reach the server on UDP port ${config.getRawConfig().gerbil.clients_start_port}?`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { db, newts, sites } from "@server/db";
|
import { db, newts, sites, targetHealthCheck, targets } from "@server/db";
|
||||||
import {
|
import {
|
||||||
hasActiveConnections,
|
hasActiveConnections,
|
||||||
getClientConfigVersion
|
getClientConfigVersion
|
||||||
@@ -78,6 +78,32 @@ export const startNewtOfflineChecker = (): void => {
|
|||||||
.update(sites)
|
.update(sites)
|
||||||
.set({ online: false })
|
.set({ online: false })
|
||||||
.where(eq(sites.siteId, staleSite.siteId));
|
.where(eq(sites.siteId, staleSite.siteId));
|
||||||
|
|
||||||
|
const healthChecksOnSite = await db
|
||||||
|
.select()
|
||||||
|
.from(targetHealthCheck)
|
||||||
|
.innerJoin(
|
||||||
|
targets,
|
||||||
|
eq(targets.targetId, targetHealthCheck.targetId)
|
||||||
|
)
|
||||||
|
.innerJoin(sites, eq(sites.siteId, targets.siteId))
|
||||||
|
.where(eq(sites.siteId, staleSite.siteId));
|
||||||
|
|
||||||
|
for (const healthCheck of healthChecksOnSite) {
|
||||||
|
logger.info(
|
||||||
|
`Marking health check ${healthCheck.targetHealthCheck.targetHealthCheckId} offline due to site ${staleSite.siteId} being marked offline`
|
||||||
|
);
|
||||||
|
await db
|
||||||
|
.update(targetHealthCheck)
|
||||||
|
.set({ hcHealth: "unknown" })
|
||||||
|
.where(
|
||||||
|
eq(
|
||||||
|
targetHealthCheck.targetHealthCheckId,
|
||||||
|
healthCheck.targetHealthCheck
|
||||||
|
.targetHealthCheckId
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this part only effects self hosted. Its not efficient but we dont expect people to have very many wireguard sites
|
// this part only effects self hosted. Its not efficient but we dont expect people to have very many wireguard sites
|
||||||
@@ -102,7 +128,8 @@ export const startNewtOfflineChecker = (): void => {
|
|||||||
|
|
||||||
// loop over each one. If its offline and there is a new update then mark it online. If its online and there is no update then mark it offline
|
// loop over each one. If its offline and there is a new update then mark it online. If its online and there is no update then mark it offline
|
||||||
for (const site of allWireguardSites) {
|
for (const site of allWireguardSites) {
|
||||||
const lastBandwidthUpdate = new Date(site.lastBandwidthUpdate!).getTime() / 1000;
|
const lastBandwidthUpdate =
|
||||||
|
new Date(site.lastBandwidthUpdate!).getTime() / 1000;
|
||||||
if (
|
if (
|
||||||
lastBandwidthUpdate < wireguardOfflineThreshold &&
|
lastBandwidthUpdate < wireguardOfflineThreshold &&
|
||||||
site.online
|
site.online
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { handleFingerprintInsertion } from "./fingerprintingUtils";
|
|||||||
import { Alias } from "@server/lib/ip";
|
import { Alias } from "@server/lib/ip";
|
||||||
import { build } from "@server/build";
|
import { build } from "@server/build";
|
||||||
import { canCompress } from "@server/lib/clientVersionChecks";
|
import { canCompress } from "@server/lib/clientVersionChecks";
|
||||||
|
import config from "@server/lib/config";
|
||||||
|
|
||||||
export const handleOlmRegisterMessage: MessageHandler = async (context) => {
|
export const handleOlmRegisterMessage: MessageHandler = async (context) => {
|
||||||
logger.info("Handling register olm message!");
|
logger.info("Handling register olm message!");
|
||||||
@@ -274,7 +275,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
|
|||||||
// TODO: I still think there is a better way to do this rather than locking it out here but ???
|
// TODO: I still think there is a better way to do this rather than locking it out here but ???
|
||||||
if (now - (client.lastHolePunch || 0) > 5 && sitesCount > 0) {
|
if (now - (client.lastHolePunch || 0) > 5 && sitesCount > 0) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
"Client last hole punch is too old and we have sites to send; skipping this register"
|
`Client last hole punch is too old and we have sites to send; skipping this register. The client is failing to hole punch and identify its network address with the server. Can the client reach the server on UDP port ${config.getRawConfig().gerbil.clients_start_port}?`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ export const handleHealthcheckStatusMessage: MessageHandler = async (
|
|||||||
const [targetCheck] = await db
|
const [targetCheck] = await db
|
||||||
.select({
|
.select({
|
||||||
targetId: targets.targetId,
|
targetId: targets.targetId,
|
||||||
siteId: targets.siteId
|
siteId: targets.siteId,
|
||||||
|
hcStatus: targetHealthCheck.hcHealth
|
||||||
})
|
})
|
||||||
.from(targets)
|
.from(targets)
|
||||||
.innerJoin(
|
.innerJoin(
|
||||||
@@ -85,6 +86,7 @@ export const handleHealthcheckStatusMessage: MessageHandler = async (
|
|||||||
eq(targets.resourceId, resources.resourceId)
|
eq(targets.resourceId, resources.resourceId)
|
||||||
)
|
)
|
||||||
.innerJoin(sites, eq(targets.siteId, sites.siteId))
|
.innerJoin(sites, eq(targets.siteId, sites.siteId))
|
||||||
|
.innerJoin(targetHealthCheck, eq(targets.targetId, targetHealthCheck.targetId))
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
eq(targets.targetId, targetIdNum),
|
eq(targets.targetId, targetIdNum),
|
||||||
@@ -101,6 +103,14 @@ export const handleHealthcheckStatusMessage: MessageHandler = async (
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if the status has changed
|
||||||
|
if (targetCheck.hcStatus === healthStatus.status) {
|
||||||
|
logger.debug(
|
||||||
|
`Health status for target ${targetId} is already ${healthStatus.status}, skipping update`
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the target's health status in the database
|
// Update the target's health status in the database
|
||||||
await db
|
await db
|
||||||
.update(targetHealthCheck)
|
.update(targetHealthCheck)
|
||||||
|
|||||||
@@ -104,6 +104,42 @@ export default async function migration() {
|
|||||||
CONSTRAINT "userOrgRoles_userId_orgId_roleId_unique" UNIQUE("userId","orgId","roleId")
|
CONSTRAINT "userOrgRoles_userId_orgId_roleId_unique" UNIQUE("userId","orgId","roleId")
|
||||||
);
|
);
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE TABLE "eventStreamingCursors" (
|
||||||
|
"cursorId" serial PRIMARY KEY NOT NULL,
|
||||||
|
"destinationId" integer NOT NULL,
|
||||||
|
"logType" varchar(50) NOT NULL,
|
||||||
|
"lastSentId" bigint DEFAULT 0 NOT NULL,
|
||||||
|
"lastSentAt" bigint
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE TABLE "eventStreamingDestinations" (
|
||||||
|
"destinationId" serial PRIMARY KEY NOT NULL,
|
||||||
|
"orgId" varchar(255) NOT NULL,
|
||||||
|
"sendConnectionLogs" boolean DEFAULT false NOT NULL,
|
||||||
|
"sendRequestLogs" boolean DEFAULT false NOT NULL,
|
||||||
|
"sendActionLogs" boolean DEFAULT false NOT NULL,
|
||||||
|
"sendAccessLogs" boolean DEFAULT false NOT NULL,
|
||||||
|
"type" varchar(50) NOT NULL,
|
||||||
|
"config" text NOT NULL,
|
||||||
|
"enabled" boolean DEFAULT true NOT NULL,
|
||||||
|
"createdAt" bigint NOT NULL,
|
||||||
|
"updatedAt" bigint NOT NULL
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(
|
||||||
|
sql`ALTER TABLE "eventStreamingCursors" ADD CONSTRAINT "eventStreamingCursors_destinationId_eventStreamingDestinations_destinationId_fk" FOREIGN KEY ("destinationId") REFERENCES "public"."eventStreamingDestinations"("destinationId") ON DELETE cascade ON UPDATE no action;`
|
||||||
|
);
|
||||||
|
await db.execute(
|
||||||
|
sql`ALTER TABLE "eventStreamingDestinations" ADD CONSTRAINT "eventStreamingDestinations_orgId_orgs_orgId_fk" FOREIGN KEY ("orgId") REFERENCES "public"."orgs"("orgId") ON DELETE cascade ON UPDATE no action;`
|
||||||
|
);
|
||||||
|
await db.execute(
|
||||||
|
sql`CREATE UNIQUE INDEX "idx_eventStreamingCursors_dest_type" ON "eventStreamingCursors" USING btree ("destinationId","logType");`
|
||||||
|
);
|
||||||
await db.execute(
|
await db.execute(
|
||||||
sql`ALTER TABLE "userOrgs" DROP CONSTRAINT "userOrgs_roleId_roles_roleId_fk";`
|
sql`ALTER TABLE "userOrgs" DROP CONSTRAINT "userOrgs_roleId_roles_roleId_fk";`
|
||||||
);
|
);
|
||||||
@@ -177,8 +213,12 @@ export default async function migration() {
|
|||||||
sql`CREATE INDEX "idx_accessAuditLog_siteResourceId" ON "connectionAuditLog" USING btree ("siteResourceId");`
|
sql`CREATE INDEX "idx_accessAuditLog_siteResourceId" ON "connectionAuditLog" USING btree ("siteResourceId");`
|
||||||
);
|
);
|
||||||
await db.execute(sql`ALTER TABLE "userInvites" DROP COLUMN "roleId";`);
|
await db.execute(sql`ALTER TABLE "userInvites" DROP COLUMN "roleId";`);
|
||||||
await db.execute(sql`ALTER TABLE "siteProvisioningKeys" ADD COLUMN "approveNewSites" boolean DEFAULT true NOT NULL;`);
|
await db.execute(
|
||||||
await db.execute(sql`ALTER TABLE "sites" ADD COLUMN "status" varchar DEFAULT 'approved';`);
|
sql`ALTER TABLE "siteProvisioningKeys" ADD COLUMN "approveNewSites" boolean DEFAULT true NOT NULL;`
|
||||||
|
);
|
||||||
|
await db.execute(
|
||||||
|
sql`ALTER TABLE "sites" ADD COLUMN "status" varchar DEFAULT 'approved';`
|
||||||
|
);
|
||||||
|
|
||||||
await db.execute(sql`COMMIT`);
|
await db.execute(sql`COMMIT`);
|
||||||
console.log("Migrated database");
|
console.log("Migrated database");
|
||||||
|
|||||||
@@ -76,9 +76,15 @@ export default async function migration() {
|
|||||||
`
|
`
|
||||||
).run();
|
).run();
|
||||||
|
|
||||||
db.prepare(`CREATE INDEX 'idx_accessAuditLog_startedAt' ON 'connectionAuditLog' ('startedAt');`).run();
|
db.prepare(
|
||||||
db.prepare(`CREATE INDEX 'idx_accessAuditLog_org_startedAt' ON 'connectionAuditLog' ('orgId','startedAt');`).run();
|
`CREATE INDEX 'idx_accessAuditLog_startedAt' ON 'connectionAuditLog' ('startedAt');`
|
||||||
db.prepare(`CREATE INDEX 'idx_accessAuditLog_siteResourceId' ON 'connectionAuditLog' ('siteResourceId');`).run();
|
).run();
|
||||||
|
db.prepare(
|
||||||
|
`CREATE INDEX 'idx_accessAuditLog_org_startedAt' ON 'connectionAuditLog' ('orgId','startedAt');`
|
||||||
|
).run();
|
||||||
|
db.prepare(
|
||||||
|
`CREATE INDEX 'idx_accessAuditLog_siteResourceId' ON 'connectionAuditLog' ('siteResourceId');`
|
||||||
|
).run();
|
||||||
|
|
||||||
db.prepare(
|
db.prepare(
|
||||||
`
|
`
|
||||||
@@ -168,6 +174,42 @@ export default async function migration() {
|
|||||||
);
|
);
|
||||||
`
|
`
|
||||||
).run();
|
).run();
|
||||||
|
|
||||||
|
db.prepare(
|
||||||
|
`
|
||||||
|
CREATE TABLE 'eventStreamingCursors' (
|
||||||
|
'cursorId' integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||||
|
'destinationId' integer NOT NULL,
|
||||||
|
'logType' text NOT NULL,
|
||||||
|
'lastSentId' integer DEFAULT 0 NOT NULL,
|
||||||
|
'lastSentAt' integer,
|
||||||
|
FOREIGN KEY ('destinationId') REFERENCES 'eventStreamingDestinations'('destinationId') ON UPDATE no action ON DELETE cascade
|
||||||
|
);
|
||||||
|
`
|
||||||
|
).run();
|
||||||
|
db.prepare(
|
||||||
|
`
|
||||||
|
CREATE UNIQUE INDEX 'idx_eventStreamingCursors_dest_type' ON 'eventStreamingCursors' ('destinationId','logType');--> statement-breakpoint
|
||||||
|
`
|
||||||
|
).run();
|
||||||
|
db.prepare(
|
||||||
|
`
|
||||||
|
CREATE TABLE 'eventStreamingDestinations' (
|
||||||
|
'destinationId' integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||||
|
'orgId' text NOT NULL,
|
||||||
|
'sendConnectionLogs' integer DEFAULT false NOT NULL,
|
||||||
|
'sendRequestLogs' integer DEFAULT false NOT NULL,
|
||||||
|
'sendActionLogs' integer DEFAULT false NOT NULL,
|
||||||
|
'sendAccessLogs' integer DEFAULT false NOT NULL,
|
||||||
|
'type' text NOT NULL,
|
||||||
|
'config' text NOT NULL,
|
||||||
|
'enabled' integer DEFAULT true NOT NULL,
|
||||||
|
'createdAt' integer NOT NULL,
|
||||||
|
'updatedAt' integer NOT NULL,
|
||||||
|
FOREIGN KEY ('orgId') REFERENCES 'orgs'('orgId') ON UPDATE no action ON DELETE cascade
|
||||||
|
);
|
||||||
|
`
|
||||||
|
).run();
|
||||||
db.prepare(
|
db.prepare(
|
||||||
`INSERT INTO '__new_userInvites'("inviteId", "orgId", "email", "expiresAt", "token") SELECT "inviteId", "orgId", "email", "expiresAt", "token" FROM 'userInvites';`
|
`INSERT INTO '__new_userInvites'("inviteId", "orgId", "email", "expiresAt", "token") SELECT "inviteId", "orgId", "email", "expiresAt", "token" FROM 'userInvites';`
|
||||||
).run();
|
).run();
|
||||||
@@ -191,8 +233,12 @@ export default async function migration() {
|
|||||||
`ALTER TABLE 'user' ADD 'marketingEmailConsent' integer DEFAULT false;`
|
`ALTER TABLE 'user' ADD 'marketingEmailConsent' integer DEFAULT false;`
|
||||||
).run();
|
).run();
|
||||||
db.prepare(`ALTER TABLE 'user' ADD 'locale' text;`).run();
|
db.prepare(`ALTER TABLE 'user' ADD 'locale' text;`).run();
|
||||||
db.prepare(`ALTER TABLE 'siteProvisioningKeys' ADD COLUMN 'approveNewSites' integer DEFAULT 1 NOT NULL;`).run();
|
db.prepare(
|
||||||
db.prepare(`ALTER TABLE 'sites' ADD COLUMN 'status' text DEFAULT 'approved';`).run();
|
`ALTER TABLE 'siteProvisioningKeys' ADD COLUMN 'approveNewSites' integer DEFAULT 1 NOT NULL;`
|
||||||
|
).run();
|
||||||
|
db.prepare(
|
||||||
|
`ALTER TABLE 'sites' ADD COLUMN 'status' text DEFAULT 'approved';`
|
||||||
|
).run();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
db.pragma("foreign_keys = ON");
|
db.pragma("foreign_keys = ON");
|
||||||
|
|||||||
@@ -106,7 +106,9 @@ function DestinationCard({
|
|||||||
{/* URL preview */}
|
{/* URL preview */}
|
||||||
<p className="text-xs text-muted-foreground truncate">
|
<p className="text-xs text-muted-foreground truncate">
|
||||||
{cfg.url || (
|
{cfg.url || (
|
||||||
<span className="italic">{t("streamingNoUrlConfigured")}</span>
|
<span className="italic">
|
||||||
|
{t("streamingNoUrlConfigured")}
|
||||||
|
</span>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -160,7 +162,9 @@ function AddDestinationCard({ onClick }: { onClick: () => void }) {
|
|||||||
<div className="flex items-center justify-center w-9 h-9 rounded-md border-2 border-dashed border-current">
|
<div className="flex items-center justify-center w-9 h-9 rounded-md border-2 border-dashed border-current">
|
||||||
<Plus className="h-4 w-4" />
|
<Plus className="h-4 w-4" />
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm font-medium">{t("streamingAddDestination")}</span>
|
<span className="text-sm font-medium">
|
||||||
|
{t("streamingAddDestination")}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
@@ -186,7 +190,9 @@ function DestinationTypePicker({
|
|||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const [selected, setSelected] = useState<DestinationType>("http");
|
const [selected, setSelected] = useState<DestinationType>("http");
|
||||||
|
|
||||||
const destinationTypeOptions: ReadonlyArray<StrategyOption<DestinationType>> = [
|
const destinationTypeOptions: ReadonlyArray<
|
||||||
|
StrategyOption<DestinationType>
|
||||||
|
> = [
|
||||||
{
|
{
|
||||||
id: "http",
|
id: "http",
|
||||||
title: t("streamingHttpWebhookTitle"),
|
title: t("streamingHttpWebhookTitle"),
|
||||||
@@ -233,13 +239,19 @@ function DestinationTypePicker({
|
|||||||
<Credenza open={open} onOpenChange={onOpenChange}>
|
<Credenza open={open} onOpenChange={onOpenChange}>
|
||||||
<CredenzaContent className="sm:max-w-lg">
|
<CredenzaContent className="sm:max-w-lg">
|
||||||
<CredenzaHeader>
|
<CredenzaHeader>
|
||||||
<CredenzaTitle>{t("streamingAddDestination")}</CredenzaTitle>
|
<CredenzaTitle>
|
||||||
|
{t("streamingAddDestination")}
|
||||||
|
</CredenzaTitle>
|
||||||
<CredenzaDescription>
|
<CredenzaDescription>
|
||||||
{t("streamingTypePickerDescription")}
|
{t("streamingTypePickerDescription")}
|
||||||
</CredenzaDescription>
|
</CredenzaDescription>
|
||||||
</CredenzaHeader>
|
</CredenzaHeader>
|
||||||
<CredenzaBody>
|
<CredenzaBody>
|
||||||
<div className={isPaywalled ? "pointer-events-none opacity-50" : ""}>
|
<div
|
||||||
|
className={
|
||||||
|
isPaywalled ? "pointer-events-none opacity-50" : ""
|
||||||
|
}
|
||||||
|
>
|
||||||
<StrategySelect
|
<StrategySelect
|
||||||
options={destinationTypeOptions}
|
options={destinationTypeOptions}
|
||||||
value={selected}
|
value={selected}
|
||||||
@@ -301,10 +313,7 @@ export default function StreamingDestinationsPage() {
|
|||||||
toast({
|
toast({
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
title: t("streamingFailedToLoad"),
|
title: t("streamingFailedToLoad"),
|
||||||
description: formatAxiosError(
|
description: formatAxiosError(e, t("streamingUnexpectedError"))
|
||||||
e,
|
|
||||||
t("streamingUnexpectedError")
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -341,10 +350,7 @@ export default function StreamingDestinationsPage() {
|
|||||||
toast({
|
toast({
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
title: t("streamingFailedToUpdate"),
|
title: t("streamingFailedToUpdate"),
|
||||||
description: formatAxiosError(
|
description: formatAxiosError(e, t("streamingUnexpectedError"))
|
||||||
e,
|
|
||||||
t("streamingUnexpectedError")
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setTogglingIds((prev) => {
|
setTogglingIds((prev) => {
|
||||||
@@ -375,10 +381,7 @@ export default function StreamingDestinationsPage() {
|
|||||||
toast({
|
toast({
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
title: t("streamingFailedToDelete"),
|
title: t("streamingFailedToDelete"),
|
||||||
description: formatAxiosError(
|
description: formatAxiosError(e, t("streamingUnexpectedError"))
|
||||||
e,
|
|
||||||
t("streamingUnexpectedError")
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setDeleting(false);
|
setDeleting(false);
|
||||||
@@ -459,13 +462,14 @@ export default function StreamingDestinationsPage() {
|
|||||||
if (!v) setDeleteTarget(null);
|
if (!v) setDeleteTarget(null);
|
||||||
}}
|
}}
|
||||||
string={
|
string={
|
||||||
parseHttpConfig(deleteTarget.config).name || t("streamingDeleteDialogThisDestination")
|
parseHttpConfig(deleteTarget.config).name ||
|
||||||
|
t("streamingDeleteDialogThisDestination")
|
||||||
}
|
}
|
||||||
title={t("streamingDeleteTitle")}
|
title={t("streamingDeleteTitle")}
|
||||||
dialog={
|
dialog={
|
||||||
<p className="text-sm text-muted-foreground">
|
<p>
|
||||||
{t("streamingDeleteDialogAreYouSure")}{" "}
|
{t("streamingDeleteDialogAreYouSure")}{" "}
|
||||||
<span className="font-semibold text-foreground">
|
<span>
|
||||||
{parseHttpConfig(deleteTarget.config).name ||
|
{parseHttpConfig(deleteTarget.config).name ||
|
||||||
t("streamingDeleteDialogThisDestination")}
|
t("streamingDeleteDialogThisDestination")}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import DismissableBanner from "@app/components/DismissableBanner";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { Button } from "@app/components/ui/button";
|
import { Button } from "@app/components/ui/button";
|
||||||
import { ArrowRight, Plug } from "lucide-react";
|
import { ArrowRight, Plug } from "lucide-react";
|
||||||
|
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
|
||||||
|
import { TierFeature, tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||||
|
|
||||||
type PendingSitesPageProps = {
|
type PendingSitesPageProps = {
|
||||||
params: Promise<{ orgId: string }>;
|
params: Promise<{ orgId: string }>;
|
||||||
@@ -96,6 +98,10 @@ export default async function PendingSitesPage(props: PendingSitesPageProps) {
|
|||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</DismissableBanner>
|
</DismissableBanner>
|
||||||
|
<PaidFeaturesAlert
|
||||||
|
tiers={tierMatrix[TierFeature.SiteProvisioningKeys]}
|
||||||
|
/>
|
||||||
|
|
||||||
<PendingSitesTable
|
<PendingSitesTable
|
||||||
sites={siteRows}
|
sites={siteRows}
|
||||||
orgId={params.orgId}
|
orgId={params.orgId}
|
||||||
|
|||||||
@@ -400,7 +400,11 @@ function ProxyResourceTargetsForm({
|
|||||||
pathMatchType: row.original.pathMatchType
|
pathMatchType: row.original.pathMatchType
|
||||||
}}
|
}}
|
||||||
onChange={(config) =>
|
onChange={(config) =>
|
||||||
updateTarget(row.original.targetId, config)
|
updateTarget(row.original.targetId,
|
||||||
|
config.path === null && config.pathMatchType === null
|
||||||
|
? { ...config, rewritePath: null, rewritePathType: null }
|
||||||
|
: config
|
||||||
|
)
|
||||||
}
|
}
|
||||||
trigger={
|
trigger={
|
||||||
<Button
|
<Button
|
||||||
@@ -424,7 +428,11 @@ function ProxyResourceTargetsForm({
|
|||||||
pathMatchType: row.original.pathMatchType
|
pathMatchType: row.original.pathMatchType
|
||||||
}}
|
}}
|
||||||
onChange={(config) =>
|
onChange={(config) =>
|
||||||
updateTarget(row.original.targetId, config)
|
updateTarget(row.original.targetId,
|
||||||
|
config.path === null && config.pathMatchType === null
|
||||||
|
? { ...config, rewritePath: null, rewritePathType: null }
|
||||||
|
: config
|
||||||
|
)
|
||||||
}
|
}
|
||||||
trigger={
|
trigger={
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -776,7 +776,11 @@ export default function Page() {
|
|||||||
pathMatchType: row.original.pathMatchType
|
pathMatchType: row.original.pathMatchType
|
||||||
}}
|
}}
|
||||||
onChange={(config) =>
|
onChange={(config) =>
|
||||||
updateTarget(row.original.targetId, config)
|
updateTarget(row.original.targetId,
|
||||||
|
config.path === null && config.pathMatchType === null
|
||||||
|
? { ...config, rewritePath: null, rewritePathType: null }
|
||||||
|
: config
|
||||||
|
)
|
||||||
}
|
}
|
||||||
trigger={
|
trigger={
|
||||||
<Button
|
<Button
|
||||||
@@ -800,7 +804,11 @@ export default function Page() {
|
|||||||
pathMatchType: row.original.pathMatchType
|
pathMatchType: row.original.pathMatchType
|
||||||
}}
|
}}
|
||||||
onChange={(config) =>
|
onChange={(config) =>
|
||||||
updateTarget(row.original.targetId, config)
|
updateTarget(row.original.targetId,
|
||||||
|
config.path === null && config.pathMatchType === null
|
||||||
|
? { ...config, rewritePath: null, rewritePathType: null }
|
||||||
|
: config
|
||||||
|
)
|
||||||
}
|
}
|
||||||
trigger={
|
trigger={
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -614,6 +614,7 @@ export function InternalResourceForm({
|
|||||||
<SitesSelector
|
<SitesSelector
|
||||||
orgId={orgId}
|
orgId={orgId}
|
||||||
selectedSite={selectedSite}
|
selectedSite={selectedSite}
|
||||||
|
filterTypes={["newt"]}
|
||||||
onSelectSite={(site) => {
|
onSelectSite={(site) => {
|
||||||
setSelectedSite(site);
|
setSelectedSite(site);
|
||||||
field.onChange(site.siteId);
|
field.onChange(site.siteId);
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import { getNextSortOrder, getSortDirection } from "@app/lib/sortColumn";
|
|||||||
import { toast } from "@app/hooks/useToast";
|
import { toast } from "@app/hooks/useToast";
|
||||||
import { createApiClient, formatAxiosError } from "@app/lib/api";
|
import { createApiClient, formatAxiosError } from "@app/lib/api";
|
||||||
import { build } from "@server/build";
|
import { build } from "@server/build";
|
||||||
|
import { TierFeature, tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||||
|
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
||||||
import { type PaginationState } from "@tanstack/react-table";
|
import { type PaginationState } from "@tanstack/react-table";
|
||||||
import {
|
import {
|
||||||
ArrowDown01Icon,
|
ArrowDown01Icon,
|
||||||
@@ -63,6 +65,10 @@ export default function PendingSitesTable({
|
|||||||
|
|
||||||
const api = createApiClient(useEnvContext());
|
const api = createApiClient(useEnvContext());
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
|
const { isPaidUser } = usePaidStatus();
|
||||||
|
const canUseSiteProvisioning =
|
||||||
|
isPaidUser(tierMatrix[TierFeature.SiteProvisioningKeys]) &&
|
||||||
|
build !== "oss";
|
||||||
|
|
||||||
const booleanSearchFilterSchema = z
|
const booleanSearchFilterSchema = z
|
||||||
.enum(["true", "false"])
|
.enum(["true", "false"])
|
||||||
@@ -450,6 +456,7 @@ export default function PendingSitesTable({
|
|||||||
onSearch={handleSearchChange}
|
onSearch={handleSearchChange}
|
||||||
onRefresh={refreshData}
|
onRefresh={refreshData}
|
||||||
isRefreshing={isRefreshing || isFiltering}
|
isRefreshing={isRefreshing || isFiltering}
|
||||||
|
refreshButtonDisabled={!canUseSiteProvisioning}
|
||||||
rowCount={rowCount}
|
rowCount={rowCount}
|
||||||
columnVisibility={{
|
columnVisibility={{
|
||||||
niceId: false,
|
niceId: false,
|
||||||
|
|||||||
@@ -311,6 +311,7 @@ export default function SiteProvisioningKeysTable({
|
|||||||
addButtonDisabled={!canUseSiteProvisioning}
|
addButtonDisabled={!canUseSiteProvisioning}
|
||||||
onRefresh={refreshData}
|
onRefresh={refreshData}
|
||||||
isRefreshing={isRefreshing}
|
isRefreshing={isRefreshing}
|
||||||
|
refreshButtonDisabled={!canUseSiteProvisioning}
|
||||||
addButtonText={t("provisioningKeysAdd")}
|
addButtonText={t("provisioningKeysAdd")}
|
||||||
enableColumnVisibility={true}
|
enableColumnVisibility={true}
|
||||||
stickyLeftColumn="name"
|
stickyLeftColumn="name"
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ import {
|
|||||||
import { CheckboxWithLabel } from "./ui/checkbox";
|
import { CheckboxWithLabel } from "./ui/checkbox";
|
||||||
import { OptionSelect, type OptionSelectOption } from "./OptionSelect";
|
import { OptionSelect, type OptionSelectOption } from "./OptionSelect";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { FaCubes, FaDocker, FaWindows } from "react-icons/fa";
|
import { FaApple, FaCubes, FaDocker, FaLinux, FaWindows } from "react-icons/fa";
|
||||||
import { Terminal } from "lucide-react";
|
|
||||||
import { SiKubernetes, SiNixos } from "react-icons/si";
|
import { SiKubernetes, SiNixos } from "react-icons/si";
|
||||||
|
|
||||||
export type CommandItem = string | { title: string; command: string };
|
export type CommandItem = string | { title: string; command: string };
|
||||||
|
|
||||||
const PLATFORMS = [
|
const PLATFORMS = [
|
||||||
"unix",
|
"linux",
|
||||||
|
"macos",
|
||||||
"docker",
|
"docker",
|
||||||
"kubernetes",
|
"kubernetes",
|
||||||
"podman",
|
"podman",
|
||||||
@@ -43,7 +43,7 @@ export function NewtSiteInstallCommands({
|
|||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
|
|
||||||
const [acceptClients, setAcceptClients] = useState(true);
|
const [acceptClients, setAcceptClients] = useState(true);
|
||||||
const [platform, setPlatform] = useState<Platform>("unix");
|
const [platform, setPlatform] = useState<Platform>("linux");
|
||||||
const [architecture, setArchitecture] = useState(
|
const [architecture, setArchitecture] = useState(
|
||||||
() => getArchitectures(platform)[0]
|
() => getArchitectures(platform)[0]
|
||||||
);
|
);
|
||||||
@@ -54,8 +54,68 @@ export function NewtSiteInstallCommands({
|
|||||||
: "";
|
: "";
|
||||||
|
|
||||||
const commandList: Record<Platform, Record<string, CommandItem[]>> = {
|
const commandList: Record<Platform, Record<string, CommandItem[]>> = {
|
||||||
unix: {
|
linux: {
|
||||||
All: [
|
Run: [
|
||||||
|
{
|
||||||
|
title: t("install"),
|
||||||
|
command: `curl -fsSL https://static.pangolin.net/get-newt.sh | bash`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("run"),
|
||||||
|
command: `newt --id ${id} --secret ${secret} --endpoint ${endpoint}${acceptClientsFlag}`
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Systemd Service": [
|
||||||
|
{
|
||||||
|
title: t("install"),
|
||||||
|
command: `curl -fsSL https://static.pangolin.net/get-newt.sh | bash`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("envFile"),
|
||||||
|
command: `# Create the directory and environment file
|
||||||
|
sudo install -d -m 0755 /etc/newt
|
||||||
|
sudo tee /etc/newt/newt.env > /dev/null << 'EOF'
|
||||||
|
NEWT_ID=${id}
|
||||||
|
NEWT_SECRET=${secret}
|
||||||
|
PANGOLIN_ENDPOINT=${endpoint}${!acceptClients ? `
|
||||||
|
DISABLE_CLIENTS=true` : ""}
|
||||||
|
EOF
|
||||||
|
sudo chmod 600 /etc/newt/newt.env`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("serviceFile"),
|
||||||
|
command: `sudo tee /etc/systemd/system/newt.service > /dev/null << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Newt
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
Group=root
|
||||||
|
EnvironmentFile=/etc/newt/newt.env
|
||||||
|
ExecStart=/usr/local/bin/newt
|
||||||
|
Restart=always
|
||||||
|
RestartSec=2
|
||||||
|
UMask=0077
|
||||||
|
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("enableAndStart"),
|
||||||
|
command: `sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now newt`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
macos: {
|
||||||
|
Run: [
|
||||||
{
|
{
|
||||||
title: t("install"),
|
title: t("install"),
|
||||||
command: `curl -fsSL https://static.pangolin.net/get-newt.sh | bash`
|
command: `curl -fsSL https://static.pangolin.net/get-newt.sh | bash`
|
||||||
@@ -131,7 +191,7 @@ WantedBy=default.target`
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
nixos: {
|
nixos: {
|
||||||
All: [
|
Flake: [
|
||||||
`nix run 'nixpkgs#fosrl-newt' -- --id ${id} --secret ${secret} --endpoint ${endpoint}${acceptClientsFlag}`
|
`nix run 'nixpkgs#fosrl-newt' -- --id ${id} --secret ${secret} --endpoint ${endpoint}${acceptClientsFlag}`
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -172,9 +232,9 @@ WantedBy=default.target`
|
|||||||
|
|
||||||
<OptionSelect<string>
|
<OptionSelect<string>
|
||||||
label={
|
label={
|
||||||
["docker", "podman"].includes(platform)
|
platform === "windows"
|
||||||
? t("method")
|
? t("architecture")
|
||||||
: t("architecture")
|
: t("method")
|
||||||
}
|
}
|
||||||
options={getArchitectures(platform).map((arch) => ({
|
options={getArchitectures(platform).map((arch) => ({
|
||||||
value: arch,
|
value: arch,
|
||||||
@@ -261,8 +321,10 @@ function getPlatformIcon(platformName: Platform) {
|
|||||||
switch (platformName) {
|
switch (platformName) {
|
||||||
case "windows":
|
case "windows":
|
||||||
return <FaWindows className="h-4 w-4 mr-2" />;
|
return <FaWindows className="h-4 w-4 mr-2" />;
|
||||||
case "unix":
|
case "linux":
|
||||||
return <Terminal className="h-4 w-4 mr-2" />;
|
return <FaLinux className="h-4 w-4 mr-2" />;
|
||||||
|
case "macos":
|
||||||
|
return <FaApple className="h-4 w-4 mr-2" />;
|
||||||
case "docker":
|
case "docker":
|
||||||
return <FaDocker className="h-4 w-4 mr-2" />;
|
return <FaDocker className="h-4 w-4 mr-2" />;
|
||||||
case "kubernetes":
|
case "kubernetes":
|
||||||
@@ -272,7 +334,7 @@ function getPlatformIcon(platformName: Platform) {
|
|||||||
case "nixos":
|
case "nixos":
|
||||||
return <SiNixos className="h-4 w-4 mr-2" />;
|
return <SiNixos className="h-4 w-4 mr-2" />;
|
||||||
default:
|
default:
|
||||||
return <Terminal className="h-4 w-4 mr-2" />;
|
return <FaLinux className="h-4 w-4 mr-2" />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,8 +342,10 @@ function getPlatformName(platformName: Platform) {
|
|||||||
switch (platformName) {
|
switch (platformName) {
|
||||||
case "windows":
|
case "windows":
|
||||||
return "Windows";
|
return "Windows";
|
||||||
case "unix":
|
case "linux":
|
||||||
return "Unix & macOS";
|
return "Linux";
|
||||||
|
case "macos":
|
||||||
|
return "macOS";
|
||||||
case "docker":
|
case "docker":
|
||||||
return "Docker";
|
return "Docker";
|
||||||
case "kubernetes":
|
case "kubernetes":
|
||||||
@@ -291,14 +355,16 @@ function getPlatformName(platformName: Platform) {
|
|||||||
case "nixos":
|
case "nixos":
|
||||||
return "NixOS";
|
return "NixOS";
|
||||||
default:
|
default:
|
||||||
return "Unix / macOS";
|
return "Linux";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArchitectures(platform: Platform) {
|
function getArchitectures(platform: Platform) {
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case "unix":
|
case "linux":
|
||||||
return ["All"];
|
return ["Run", "Systemd Service"];
|
||||||
|
case "macos":
|
||||||
|
return ["Run"];
|
||||||
case "windows":
|
case "windows":
|
||||||
return ["x64"];
|
return ["x64"];
|
||||||
case "docker":
|
case "docker":
|
||||||
@@ -308,8 +374,8 @@ function getArchitectures(platform: Platform) {
|
|||||||
case "podman":
|
case "podman":
|
||||||
return ["Podman Quadlet", "Podman Run"];
|
return ["Podman Quadlet", "Podman Run"];
|
||||||
case "nixos":
|
case "nixos":
|
||||||
return ["All"];
|
return ["Flake"];
|
||||||
default:
|
default:
|
||||||
return ["x64"];
|
return ["Run"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,12 +24,14 @@ export type SitesSelectorProps = {
|
|||||||
orgId: string;
|
orgId: string;
|
||||||
selectedSite?: Selectedsite | null;
|
selectedSite?: Selectedsite | null;
|
||||||
onSelectSite: (selected: Selectedsite) => void;
|
onSelectSite: (selected: Selectedsite) => void;
|
||||||
|
filterTypes?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export function SitesSelector({
|
export function SitesSelector({
|
||||||
orgId,
|
orgId,
|
||||||
selectedSite,
|
selectedSite,
|
||||||
onSelectSite
|
onSelectSite,
|
||||||
|
filterTypes
|
||||||
}: SitesSelectorProps) {
|
}: SitesSelectorProps) {
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const [siteSearchQuery, setSiteSearchQuery] = useState("");
|
const [siteSearchQuery, setSiteSearchQuery] = useState("");
|
||||||
@@ -45,7 +47,9 @@ export function SitesSelector({
|
|||||||
|
|
||||||
// always include the selected site in the list of sites shown
|
// always include the selected site in the list of sites shown
|
||||||
const sitesShown = useMemo(() => {
|
const sitesShown = useMemo(() => {
|
||||||
const allSites: Array<Selectedsite> = [...sites];
|
const allSites: Array<Selectedsite> = filterTypes
|
||||||
|
? sites.filter((s) => filterTypes.includes(s.type))
|
||||||
|
: [...sites];
|
||||||
if (
|
if (
|
||||||
debouncedQuery.trim().length === 0 &&
|
debouncedQuery.trim().length === 0 &&
|
||||||
selectedSite &&
|
selectedSite &&
|
||||||
@@ -54,7 +58,7 @@ export function SitesSelector({
|
|||||||
allSites.unshift(selectedSite);
|
allSites.unshift(selectedSite);
|
||||||
}
|
}
|
||||||
return allSites;
|
return allSites;
|
||||||
}, [debouncedQuery, sites, selectedSite]);
|
}, [debouncedQuery, sites, selectedSite, filterTypes]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Command shouldFilter={false}>
|
<Command shouldFilter={false}>
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ type ControlledDataTableProps<TData, TValue> = {
|
|||||||
onAdd?: () => void;
|
onAdd?: () => void;
|
||||||
onRefresh?: () => void;
|
onRefresh?: () => void;
|
||||||
isRefreshing?: boolean;
|
isRefreshing?: boolean;
|
||||||
|
refreshButtonDisabled?: boolean;
|
||||||
isNavigatingToAddPage?: boolean;
|
isNavigatingToAddPage?: boolean;
|
||||||
searchPlaceholder?: string;
|
searchPlaceholder?: string;
|
||||||
filters?: DataTableFilter[];
|
filters?: DataTableFilter[];
|
||||||
@@ -91,6 +92,7 @@ export function ControlledDataTable<TData, TValue>({
|
|||||||
onAdd,
|
onAdd,
|
||||||
onRefresh,
|
onRefresh,
|
||||||
isRefreshing,
|
isRefreshing,
|
||||||
|
refreshButtonDisabled = false,
|
||||||
searchPlaceholder = "Search...",
|
searchPlaceholder = "Search...",
|
||||||
filters,
|
filters,
|
||||||
filterDisplayMode = "label",
|
filterDisplayMode = "label",
|
||||||
@@ -335,7 +337,7 @@ export function ControlledDataTable<TData, TValue>({
|
|||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={onRefresh}
|
onClick={onRefresh}
|
||||||
disabled={isRefreshing}
|
disabled={isRefreshing || refreshButtonDisabled}
|
||||||
>
|
>
|
||||||
<RefreshCw
|
<RefreshCw
|
||||||
className={`mr-0 sm:mr-2 h-4 w-4 ${isRefreshing ? "animate-spin" : ""}`}
|
className={`mr-0 sm:mr-2 h-4 w-4 ${isRefreshing ? "animate-spin" : ""}`}
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ type DataTableProps<TData, TValue> = {
|
|||||||
addButtonDisabled?: boolean;
|
addButtonDisabled?: boolean;
|
||||||
onRefresh?: () => void;
|
onRefresh?: () => void;
|
||||||
isRefreshing?: boolean;
|
isRefreshing?: boolean;
|
||||||
|
refreshButtonDisabled?: boolean;
|
||||||
searchPlaceholder?: string;
|
searchPlaceholder?: string;
|
||||||
searchColumn?: string;
|
searchColumn?: string;
|
||||||
defaultSort?: {
|
defaultSort?: {
|
||||||
@@ -207,6 +208,7 @@ export function DataTable<TData, TValue>({
|
|||||||
addButtonDisabled = false,
|
addButtonDisabled = false,
|
||||||
onRefresh,
|
onRefresh,
|
||||||
isRefreshing,
|
isRefreshing,
|
||||||
|
refreshButtonDisabled = false,
|
||||||
searchPlaceholder = "Search...",
|
searchPlaceholder = "Search...",
|
||||||
searchColumn = "name",
|
searchColumn = "name",
|
||||||
defaultSort,
|
defaultSort,
|
||||||
@@ -624,7 +626,7 @@ export function DataTable<TData, TValue>({
|
|||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={onRefresh}
|
onClick={onRefresh}
|
||||||
disabled={isRefreshing}
|
disabled={isRefreshing || refreshButtonDisabled}
|
||||||
>
|
>
|
||||||
<RefreshCw
|
<RefreshCw
|
||||||
className={`mr-0 sm:mr-2 h-4 w-4 ${isRefreshing ? "animate-spin" : ""}`}
|
className={`mr-0 sm:mr-2 h-4 w-4 ${isRefreshing ? "animate-spin" : ""}`}
|
||||||
|
|||||||
@@ -22,12 +22,21 @@ export async function getUserLocale(): Promise<Locale> {
|
|||||||
const res = await internal.get("/user", await authCookieHeader());
|
const res = await internal.get("/user", await authCookieHeader());
|
||||||
const userLocale = res.data?.data?.locale;
|
const userLocale = res.data?.data?.locale;
|
||||||
if (userLocale && locales.includes(userLocale as Locale)) {
|
if (userLocale && locales.includes(userLocale as Locale)) {
|
||||||
// Set the cookie so subsequent requests don't need the API call
|
// Try to cache in a cookie so subsequent requests skip the API
|
||||||
(await cookies()).set(COOKIE_NAME, userLocale, {
|
// call. cookies().set() is only permitted in Server Actions and
|
||||||
maxAge: COOKIE_MAX_AGE,
|
// Route Handlers — not during rendering — so we isolate it so
|
||||||
path: "/",
|
// that a write failure doesn't prevent the locale from being
|
||||||
sameSite: "lax"
|
// returned for the current request.
|
||||||
});
|
try {
|
||||||
|
(await cookies()).set(COOKIE_NAME, userLocale, {
|
||||||
|
maxAge: COOKIE_MAX_AGE,
|
||||||
|
path: "/",
|
||||||
|
sameSite: "lax"
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// Cannot set cookies in this context (e.g. during rendering);
|
||||||
|
// the correct locale is still returned below.
|
||||||
|
}
|
||||||
return userLocale as Locale;
|
return userLocale as Locale;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
Reference in New Issue
Block a user