diff --git a/messages/bg-BG.json b/messages/bg-BG.json index 9208a18d..f8688445 100644 --- a/messages/bg-BG.json +++ b/messages/bg-BG.json @@ -1504,5 +1504,18 @@ "internationaldomaindetected": "International Domain Detected", "willbestoredas": "Will be stored as:", "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Provided Domain", + "domainPickerFreeProvidedDomain": "Free Provided Domain", + "domainPickerVerified": "Verified", + "domainPickerUnverified": "Unverified", + "domainPickerInvalidSubdomainStructure": "This subdomain contains invalid characters or structure. It will be sanitized automatically when you save.", + "domainPickerError": "Error", + "domainPickerErrorLoadDomains": "Failed to load organization domains", + "domainPickerErrorCheckAvailability": "Failed to check domain availability", + "domainPickerInvalidSubdomain": "Invalid subdomain", + "domainPickerInvalidSubdomainRemoved": "The input \"{sub}\" was removed because it's not valid.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" could not be made valid for {domain}.", + "domainPickerSubdomainSanitized": "Subdomain sanitized", + "domainPickerSubdomainCorrected": "\"{sub}\" was corrected to \"{sanitized}\"" } diff --git a/messages/cs-CZ.json b/messages/cs-CZ.json index d1b2703e..0b99e527 100644 --- a/messages/cs-CZ.json +++ b/messages/cs-CZ.json @@ -1504,5 +1504,18 @@ "internationaldomaindetected": "International Domain Detected", "willbestoredas": "Will be stored as:", "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Provided Domain", + "domainPickerFreeProvidedDomain": "Free Provided Domain", + "domainPickerVerified": "Verified", + "domainPickerUnverified": "Unverified", + "domainPickerInvalidSubdomainStructure": "This subdomain contains invalid characters or structure. It will be sanitized automatically when you save.", + "domainPickerError": "Error", + "domainPickerErrorLoadDomains": "Failed to load organization domains", + "domainPickerErrorCheckAvailability": "Failed to check domain availability", + "domainPickerInvalidSubdomain": "Invalid subdomain", + "domainPickerInvalidSubdomainRemoved": "The input \"{sub}\" was removed because it's not valid.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" could not be made valid for {domain}.", + "domainPickerSubdomainSanitized": "Subdomain sanitized", + "domainPickerSubdomainCorrected": "\"{sub}\" was corrected to \"{sanitized}\"" } diff --git a/messages/de-DE.json b/messages/de-DE.json index a3bc6be3..795108ae 100644 --- a/messages/de-DE.json +++ b/messages/de-DE.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "Beim Hinzufügen des Benutzers zur Rolle ist ein Fehler aufgetreten.", "userSaved": "Benutzer gespeichert", "userSavedDescription": "Der Benutzer wurde aktualisiert.", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "Automatisch vorgesehen", + "autoProvisionedDescription": "Erlaube diesem Benutzer die automatische Verwaltung durch Identitätsanbieter", "accessControlsDescription": "Verwalten Sie, worauf dieser Benutzer in der Organisation zugreifen und was er tun kann", "accessControlsSubmit": "Zugriffskontrollen speichern", "roles": "Rollen", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "Professional Edition erforderlich", "licenseTierProfessionalRequiredDescription": "Diese Funktion ist nur in der Professional Edition verfügbar.", "actionGetOrg": "Organisation abrufen", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "Org Benutzer aktualisieren", + "createOrgUser": "Org Benutzer erstellen", "actionUpdateOrg": "Organisation aktualisieren", "actionUpdateUser": "Benutzer aktualisieren", "actionGetUser": "Benutzer abrufen", @@ -1503,6 +1503,19 @@ }, "internationaldomaindetected": "Internationale Domain erkannt", "willbestoredas": "Wird gespeichert als:", - "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpGoogleDescription": "Google OAuth2/OIDC Provider", + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Angegebene Domain", + "domainPickerFreeProvidedDomain": "Kostenlose Domain", + "domainPickerVerified": "Verifiziert", + "domainPickerUnverified": "Nicht verifiziert", + "domainPickerInvalidSubdomainStructure": "Diese Subdomain enthält ungültige Zeichen oder Struktur. Sie wird beim Speichern automatisch bereinigt.", + "domainPickerError": "Fehler", + "domainPickerErrorLoadDomains": "Fehler beim Laden der Organisations-Domänen", + "domainPickerErrorCheckAvailability": "Fehler beim Prüfen der Domain-Verfügbarkeit", + "domainPickerInvalidSubdomain": "Ungültige Subdomain", + "domainPickerInvalidSubdomainRemoved": "Die Eingabe \"{sub}\" wurde entfernt, weil sie nicht gültig ist.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" konnte nicht für {domain} gültig gemacht werden.", + "domainPickerSubdomainSanitized": "Subdomain bereinigt", + "domainPickerSubdomainCorrected": "\"{sub}\" wurde korrigiert zu \"{sanitized}\"" } diff --git a/messages/en-US.json b/messages/en-US.json index 48442a1a..abd5bd52 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -1507,6 +1507,19 @@ "idpGoogleDescription": "Google OAuth2/OIDC provider", "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", "customHeaders": "Custom Headers", - "customHeadersDescription": "Headers new line separated: Header-Name: value", - "headersValidationError": "Headers must be in the format: Header-Name: value" -} \ No newline at end of file + "customHeadersDescription": "Headers new line separated: Header-Name: value.", + "headersValidationError": "Headers must be in the format: Header-Name: value.", + "domainPickerProvidedDomain": "Provided Domain", + "domainPickerFreeProvidedDomain": "Free Provided Domain", + "domainPickerVerified": "Verified", + "domainPickerUnverified": "Unverified", + "domainPickerInvalidSubdomainStructure": "This subdomain contains invalid characters or structure. It will be sanitized automatically when you save.", + "domainPickerError": "Error", + "domainPickerErrorLoadDomains": "Failed to load organization domains", + "domainPickerErrorCheckAvailability": "Failed to check domain availability", + "domainPickerInvalidSubdomain": "Invalid subdomain", + "domainPickerInvalidSubdomainRemoved": "The input \"{sub}\" was removed because it's not valid.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" could not be made valid for {domain}.", + "domainPickerSubdomainSanitized": "Subdomain sanitized", + "domainPickerSubdomainCorrected": "\"{sub}\" was corrected to \"{sanitized}\"" +} diff --git a/messages/es-ES.json b/messages/es-ES.json index 3be67893..08cb32ab 100644 --- a/messages/es-ES.json +++ b/messages/es-ES.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "Ocurrió un error mientras se añadía el usuario al rol.", "userSaved": "Usuario guardado", "userSavedDescription": "El usuario ha sido actualizado.", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "Auto asegurado", + "autoProvisionedDescription": "Permitir a este usuario ser administrado automáticamente por el proveedor de identidad", "accessControlsDescription": "Administrar lo que este usuario puede acceder y hacer en la organización", "accessControlsSubmit": "Guardar controles de acceso", "roles": "Roles", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "Edición Profesional requerida", "licenseTierProfessionalRequiredDescription": "Esta característica sólo está disponible en la Edición Profesional.", "actionGetOrg": "Obtener organización", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "Actualizar usuario Org", + "createOrgUser": "Crear usuario Org", "actionUpdateOrg": "Actualizar organización", "actionUpdateUser": "Actualizar usuario", "actionGetUser": "Obtener usuario", @@ -1240,7 +1240,7 @@ "newtUpdateAvailable": "Nueva actualización disponible", "newtUpdateAvailableInfo": "Hay una nueva versión de Newt disponible. Actualice a la última versión para la mejor experiencia.", "domainPickerEnterDomain": "Dominio", - "domainPickerPlaceholder": "myapp.example.com", + "domainPickerPlaceholder": "miapp.ejemplo.com", "domainPickerDescription": "Ingresa el dominio completo del recurso para ver las opciones disponibles.", "domainPickerDescriptionSaas": "Ingresa un dominio completo, subdominio o simplemente un nombre para ver las opciones disponibles", "domainPickerTabAll": "Todo", @@ -1503,6 +1503,19 @@ }, "internationaldomaindetected": "Dominio Internacional detectado", "willbestoredas": "Se almacenará como:", - "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpGoogleDescription": "Proveedor OAuth2/OIDC de Google", + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Dominio proporcionado", + "domainPickerFreeProvidedDomain": "Dominio proporcionado gratis", + "domainPickerVerified": "Verificado", + "domainPickerUnverified": "Sin verificar", + "domainPickerInvalidSubdomainStructure": "Este subdominio contiene caracteres o estructura no válidos. Se limpiará automáticamente al guardar.", + "domainPickerError": "Error", + "domainPickerErrorLoadDomains": "Error al cargar los dominios de la organización", + "domainPickerErrorCheckAvailability": "No se pudo comprobar la disponibilidad del dominio", + "domainPickerInvalidSubdomain": "Subdominio inválido", + "domainPickerInvalidSubdomainRemoved": "La entrada \"{sub}\" fue eliminada porque no es válida.", + "domainPickerInvalidSubdomainCannotMakeValid": "No se ha podido hacer válido \"{sub}\" para {domain}.", + "domainPickerSubdomainSanitized": "Subdominio saneado", + "domainPickerSubdomainCorrected": "\"{sub}\" fue corregido a \"{sanitized}\"" } diff --git a/messages/fr-FR.json b/messages/fr-FR.json index eff4b2e8..1ccadb89 100644 --- a/messages/fr-FR.json +++ b/messages/fr-FR.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "Une erreur s'est produite lors de l'ajout de l'utilisateur au rôle.", "userSaved": "Utilisateur enregistré", "userSavedDescription": "L'utilisateur a été mis à jour.", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "Auto-provisionné", + "autoProvisionedDescription": "Permettre à cet utilisateur d'être géré automatiquement par le fournisseur d'identité", "accessControlsDescription": "Gérer ce que cet utilisateur peut accéder et faire dans l'organisation", "accessControlsSubmit": "Enregistrer les contrôles d'accès", "roles": "Rôles", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "Édition Professionnelle Requise", "licenseTierProfessionalRequiredDescription": "Cette fonctionnalité n'est disponible que dans l'Édition Professionnelle.", "actionGetOrg": "Obtenir l'organisation", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "Mise à jour de l'utilisateur Org", + "createOrgUser": "Créer un utilisateur Org", "actionUpdateOrg": "Mettre à jour l'organisation", "actionUpdateUser": "Mettre à jour l'utilisateur", "actionGetUser": "Obtenir l'utilisateur", @@ -1240,7 +1240,7 @@ "newtUpdateAvailable": "Mise à jour disponible", "newtUpdateAvailableInfo": "Une nouvelle version de Newt est disponible. Veuillez mettre à jour vers la dernière version pour une meilleure expérience.", "domainPickerEnterDomain": "Domaine", - "domainPickerPlaceholder": "myapp.example.com", + "domainPickerPlaceholder": "monapp.exemple.com", "domainPickerDescription": "Entrez le domaine complet de la ressource pour voir les options disponibles.", "domainPickerDescriptionSaas": "Entrez un domaine complet, un sous-domaine ou juste un nom pour voir les options disponibles", "domainPickerTabAll": "Tous", @@ -1503,6 +1503,19 @@ }, "internationaldomaindetected": "Domaine international détecté", "willbestoredas": "Sera stocké comme :", - "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpGoogleDescription": "Fournisseur Google OAuth2/OIDC", + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Domaine fourni", + "domainPickerFreeProvidedDomain": "Domaine fourni gratuitement", + "domainPickerVerified": "Vérifié", + "domainPickerUnverified": "Non vérifié", + "domainPickerInvalidSubdomainStructure": "Ce sous-domaine contient des caractères ou une structure non valide. Il sera automatiquement nettoyé lorsque vous enregistrez.", + "domainPickerError": "Erreur", + "domainPickerErrorLoadDomains": "Impossible de charger les domaines de l'organisation", + "domainPickerErrorCheckAvailability": "Impossible de vérifier la disponibilité du domaine", + "domainPickerInvalidSubdomain": "Sous-domaine invalide", + "domainPickerInvalidSubdomainRemoved": "L'entrée \"{sub}\" a été supprimée car elle n'est pas valide.", + "domainPickerInvalidSubdomainCannotMakeValid": "La «{sub}» n'a pas pu être validée pour {domain}.", + "domainPickerSubdomainSanitized": "Sous-domaine nettoyé", + "domainPickerSubdomainCorrected": "\"{sub}\" a été corrigé à \"{sanitized}\"" } diff --git a/messages/it-IT.json b/messages/it-IT.json index 377fe4ce..21c480ad 100644 --- a/messages/it-IT.json +++ b/messages/it-IT.json @@ -455,7 +455,7 @@ "userSaved": "Utente salvato", "userSavedDescription": "L'utente è stato aggiornato.", "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisionedDescription": "Permetti a questo utente di essere gestito automaticamente dal provider di identità", "accessControlsDescription": "Gestisci cosa questo utente può accedere e fare nell'organizzazione", "accessControlsSubmit": "Salva Controlli di Accesso", "roles": "Ruoli", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "Edizione Professional Richiesta", "licenseTierProfessionalRequiredDescription": "Questa funzionalità è disponibile solo nell'Edizione Professional.", "actionGetOrg": "Ottieni Organizzazione", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "Aggiorna Utente Org", + "createOrgUser": "Crea Utente Org", "actionUpdateOrg": "Aggiorna Organizzazione", "actionUpdateUser": "Aggiorna Utente", "actionGetUser": "Ottieni Utente", @@ -1504,5 +1504,18 @@ "internationaldomaindetected": "Dominio Internazionale Rilevato", "willbestoredas": "Verrà conservato come:", "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Dominio Fornito", + "domainPickerFreeProvidedDomain": "Dominio Fornito Gratuito", + "domainPickerVerified": "Verificato", + "domainPickerUnverified": "Non Verificato", + "domainPickerInvalidSubdomainStructure": "Questo sottodominio contiene caratteri o struttura non validi. Sarà sanificato automaticamente quando si salva.", + "domainPickerError": "Errore", + "domainPickerErrorLoadDomains": "Impossibile caricare i domini dell'organizzazione", + "domainPickerErrorCheckAvailability": "Impossibile verificare la disponibilità del dominio", + "domainPickerInvalidSubdomain": "Sottodominio non valido", + "domainPickerInvalidSubdomainRemoved": "L'input \"{sub}\" è stato rimosso perché non è valido.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" non può essere reso valido per {domain}.", + "domainPickerSubdomainSanitized": "Sottodominio igienizzato", + "domainPickerSubdomainCorrected": "\"{sub}\" è stato corretto in \"{sanitized}\"" } diff --git a/messages/ko-KR.json b/messages/ko-KR.json index 722e83ac..b95bf34f 100644 --- a/messages/ko-KR.json +++ b/messages/ko-KR.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "사용자를 역할에 추가하는 동안 오류가 발생했습니다.", "userSaved": "사용자 저장됨", "userSavedDescription": "사용자가 업데이트되었습니다.", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "자동 프로비저닝됨", + "autoProvisionedDescription": "이 사용자가 ID 공급자에 의해 자동으로 관리될 수 있도록 허용합니다", "accessControlsDescription": "이 사용자가 조직에서 접근하고 수행할 수 있는 작업을 관리하세요", "accessControlsSubmit": "접근 제어 저장", "roles": "역할", @@ -913,8 +913,8 @@ "idpConnectingToFinished": "연결됨", "idpErrorConnectingTo": "{name}에 연결하는 데 문제가 발생했습니다. 관리자에게 문의하십시오.", "idpErrorNotFound": "IdP를 찾을 수 없습니다.", - "idpGoogleAlt": "Google", - "idpAzureAlt": "Azure", + "idpGoogleAlt": "구글", + "idpAzureAlt": "애저", "inviteInvalid": "유효하지 않은 초대", "inviteInvalidDescription": "초대 링크가 유효하지 않습니다.", "inviteErrorWrongUser": "이 초대는 이 사용자에게 해당되지 않습니다", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "전문 에디션이 필요합니다.", "licenseTierProfessionalRequiredDescription": "이 기능은 Professional Edition에서만 사용할 수 있습니다.", "actionGetOrg": "조직 가져오기", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "조직 사용자 업데이트", + "createOrgUser": "조직 사용자 생성", "actionUpdateOrg": "조직 업데이트", "actionUpdateUser": "사용자 업데이트", "actionGetUser": "사용자 조회", @@ -1503,6 +1503,19 @@ }, "internationaldomaindetected": "국제 도메인 감지됨", "willbestoredas": "다음으로 저장됩니다:", - "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpGoogleDescription": "Google OAuth2/OIDC 공급자", + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC 공급자", + "domainPickerProvidedDomain": "제공된 도메인", + "domainPickerFreeProvidedDomain": "무료 제공된 도메인", + "domainPickerVerified": "검증됨", + "domainPickerUnverified": "검증되지 않음", + "domainPickerInvalidSubdomainStructure": "이 하위 도메인은 잘못된 문자 또는 구조를 포함하고 있습니다. 저장 시 자동으로 정리됩니다.", + "domainPickerError": "오류", + "domainPickerErrorLoadDomains": "조직 도메인 로드 실패", + "domainPickerErrorCheckAvailability": "도메인 가용성 확인 실패", + "domainPickerInvalidSubdomain": "잘못된 하위 도메인", + "domainPickerInvalidSubdomainRemoved": "입력 \"{sub}\"이(가) 유효하지 않으므로 제거되었습니다.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\"을(를) {domain}에 대해 유효하게 만들 수 없습니다.", + "domainPickerSubdomainSanitized": "하위 도메인 정리됨", + "domainPickerSubdomainCorrected": "\"{sub}\"이(가) \"{sanitized}\"로 수정되었습니다" } diff --git a/messages/nb-NO.json b/messages/nb-NO.json index ca2dec97..3990c5e2 100644 --- a/messages/nb-NO.json +++ b/messages/nb-NO.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "Det oppstod en feil under tilordning av brukeren til rollen.", "userSaved": "Bruker lagret", "userSavedDescription": "Brukeren har blitt oppdatert.", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "Auto avlyst", + "autoProvisionedDescription": "Tillat denne brukeren å bli automatisk administrert av en identitetsleverandør", "accessControlsDescription": "Administrer hva denne brukeren kan få tilgang til og gjøre i organisasjonen", "accessControlsSubmit": "Lagre tilgangskontroller", "roles": "Roller", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "Profesjonell utgave påkrevd", "licenseTierProfessionalRequiredDescription": "Denne funksjonen er kun tilgjengelig i den profesjonelle utgaven.", "actionGetOrg": "Hent organisasjon", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "Oppdater org.bruker", + "createOrgUser": "Opprett Org bruker", "actionUpdateOrg": "Oppdater organisasjon", "actionUpdateUser": "Oppdater bruker", "actionGetUser": "Hent bruker", @@ -1240,7 +1240,7 @@ "newtUpdateAvailable": "Oppdatering tilgjengelig", "newtUpdateAvailableInfo": "En ny versjon av Newt er tilgjengelig. Vennligst oppdater til den nyeste versjonen for den beste opplevelsen.", "domainPickerEnterDomain": "Domene", - "domainPickerPlaceholder": "myapp.example.com", + "domainPickerPlaceholder": "minapp.eksempel.no", "domainPickerDescription": "Skriv inn hele domenet til ressursen for å se tilgjengelige alternativer.", "domainPickerDescriptionSaas": "Skriv inn et fullt domene, underdomene eller bare et navn for å se tilgjengelige alternativer", "domainPickerTabAll": "Alle", @@ -1503,6 +1503,19 @@ }, "internationaldomaindetected": "Internasjonalt domene oppdaget", "willbestoredas": "Vil bli lagret som:", - "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpGoogleDescription": "Google OAuth2/OIDC leverandør", + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Gitt domene", + "domainPickerFreeProvidedDomain": "Gratis oppgitt domene", + "domainPickerVerified": "Bekreftet", + "domainPickerUnverified": "Uverifisert", + "domainPickerInvalidSubdomainStructure": "Dette underdomenet inneholder ugyldige tegn eller struktur. Det vil automatisk bli utsatt når du lagrer.", + "domainPickerError": "Feil", + "domainPickerErrorLoadDomains": "Kan ikke laste organisasjonens domener", + "domainPickerErrorCheckAvailability": "Kunne ikke kontrollere domenetilgjengelighet", + "domainPickerInvalidSubdomain": "Ugyldig underdomene", + "domainPickerInvalidSubdomainRemoved": "Inndata \"{sub}\" ble fjernet fordi det ikke er gyldig.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" kunne ikke gjøres gyldig for {domain}.", + "domainPickerSubdomainSanitized": "Underdomenet som ble sanivert", + "domainPickerSubdomainCorrected": "\"{sub}\" var korrigert til \"{sanitized}\"" } diff --git a/messages/nl-NL.json b/messages/nl-NL.json index 4c209e09..c6c83995 100644 --- a/messages/nl-NL.json +++ b/messages/nl-NL.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "Er is een fout opgetreden tijdens het toevoegen van de rol.", "userSaved": "Gebruiker opgeslagen", "userSavedDescription": "De gebruiker is bijgewerkt.", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "Automatisch bevestigen", + "autoProvisionedDescription": "Toestaan dat deze gebruiker automatisch wordt beheerd door een identiteitsprovider", "accessControlsDescription": "Beheer wat deze gebruiker toegang heeft tot en doet in de organisatie", "accessControlsSubmit": "Bewaar Toegangsbesturing", "roles": "Rollen", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "Professionele editie vereist", "licenseTierProfessionalRequiredDescription": "Deze functie is alleen beschikbaar in de Professional Edition.", "actionGetOrg": "Krijg Organisatie", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "Org gebruiker bijwerken", + "createOrgUser": "Org gebruiker aanmaken", "actionUpdateOrg": "Organisatie bijwerken", "actionUpdateUser": "Gebruiker bijwerken", "actionGetUser": "Gebruiker ophalen", @@ -1240,7 +1240,7 @@ "newtUpdateAvailable": "Update beschikbaar", "newtUpdateAvailableInfo": "Er is een nieuwe versie van Newt beschikbaar. Update naar de nieuwste versie voor de beste ervaring.", "domainPickerEnterDomain": "Domein", - "domainPickerPlaceholder": "myapp.example.com", + "domainPickerPlaceholder": "mijnapp.voorbeeld.nl", "domainPickerDescription": "Voer de volledige domein van de bron in om beschikbare opties te zien.", "domainPickerDescriptionSaas": "Voer een volledig domein, subdomein of gewoon een naam in om beschikbare opties te zien", "domainPickerTabAll": "Alles", @@ -1504,5 +1504,18 @@ "internationaldomaindetected": "Internationaal Domein Gedetecteerd", "willbestoredas": "Zal worden opgeslagen als:", "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Opgegeven domein", + "domainPickerFreeProvidedDomain": "Gratis verstrekt domein", + "domainPickerVerified": "Geverifieerd", + "domainPickerUnverified": "Ongeverifieerd", + "domainPickerInvalidSubdomainStructure": "Dit subdomein bevat ongeldige tekens of structuur. Het zal automatisch worden gesaneerd wanneer u opslaat.", + "domainPickerError": "Foutmelding", + "domainPickerErrorLoadDomains": "Fout bij het laden van organisatiedomeinen", + "domainPickerErrorCheckAvailability": "Kan domein beschikbaarheid niet controleren", + "domainPickerInvalidSubdomain": "Ongeldig subdomein", + "domainPickerInvalidSubdomainRemoved": "De invoer \"{sub}\" is verwijderd omdat het niet geldig is.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" kon niet geldig worden gemaakt voor {domain}.", + "domainPickerSubdomainSanitized": "Subdomein gesaniseerd", + "domainPickerSubdomainCorrected": "\"{sub}\" was gecorrigeerd op \"{sanitized}\"" } diff --git a/messages/pl-PL.json b/messages/pl-PL.json index 4ad81acc..547cc39b 100644 --- a/messages/pl-PL.json +++ b/messages/pl-PL.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "Wystąpił błąd podczas dodawania użytkownika do roli.", "userSaved": "Użytkownik zapisany", "userSavedDescription": "Użytkownik został zaktualizowany.", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "Przesłane automatycznie", + "autoProvisionedDescription": "Pozwól temu użytkownikowi na automatyczne zarządzanie przez dostawcę tożsamości", "accessControlsDescription": "Zarządzaj tym, do czego użytkownik ma dostęp i co może robić w organizacji", "accessControlsSubmit": "Zapisz kontrole dostępu", "roles": "Role", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "Wymagana edycja Professional", "licenseTierProfessionalRequiredDescription": "Ta funkcja jest dostępna tylko w edycji Professional.", "actionGetOrg": "Pobierz organizację", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "Aktualizuj użytkownika Org", + "createOrgUser": "Utwórz użytkownika Org", "actionUpdateOrg": "Aktualizuj organizację", "actionUpdateUser": "Zaktualizuj użytkownika", "actionGetUser": "Pobierz użytkownika", @@ -1240,7 +1240,7 @@ "newtUpdateAvailable": "Dostępna aktualizacja", "newtUpdateAvailableInfo": "Nowa wersja Newt jest dostępna. Prosimy o aktualizację do najnowszej wersji dla najlepszej pracy.", "domainPickerEnterDomain": "Domena", - "domainPickerPlaceholder": "myapp.example.com", + "domainPickerPlaceholder": "mojapp.example.com", "domainPickerDescription": "Wpisz pełną domenę zasobu, aby zobaczyć dostępne opcje.", "domainPickerDescriptionSaas": "Wprowadź pełną domenę, subdomenę lub po prostu nazwę, aby zobaczyć dostępne opcje", "domainPickerTabAll": "Wszystko", @@ -1503,6 +1503,19 @@ }, "internationaldomaindetected": "Wykryto międzynarodową domenę", "willbestoredas": "Będą przechowywane jako:", - "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpGoogleDescription": "Dostawca Google OAuth2/OIDC", + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Dostarczona domena", + "domainPickerFreeProvidedDomain": "Darmowa oferowana domena", + "domainPickerVerified": "Zweryfikowano", + "domainPickerUnverified": "Niezweryfikowane", + "domainPickerInvalidSubdomainStructure": "Ta subdomena zawiera nieprawidłowe znaki lub strukturę. Zostanie ona automatycznie oczyszczona po zapisaniu.", + "domainPickerError": "Błąd", + "domainPickerErrorLoadDomains": "Nie udało się załadować domen organizacji", + "domainPickerErrorCheckAvailability": "Nie udało się sprawdzić dostępności domeny", + "domainPickerInvalidSubdomain": "Nieprawidłowa subdomena", + "domainPickerInvalidSubdomainRemoved": "Wejście \"{sub}\" zostało usunięte, ponieważ jest nieprawidłowe.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" nie może być poprawne dla {domain}.", + "domainPickerSubdomainSanitized": "Poddomena oczyszczona", + "domainPickerSubdomainCorrected": "\"{sub}\" został skorygowany do \"{sanitized}\"" } diff --git a/messages/pt-PT.json b/messages/pt-PT.json index 585983d7..86584761 100644 --- a/messages/pt-PT.json +++ b/messages/pt-PT.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "Ocorreu um erro ao adicionar usuário à função.", "userSaved": "Usuário salvo", "userSavedDescription": "O usuário foi atualizado.", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "Auto provisionado", + "autoProvisionedDescription": "Permitir que este usuário seja gerenciado automaticamente pelo provedor de identidade", "accessControlsDescription": "Gerencie o que este usuário pode acessar e fazer na organização", "accessControlsSubmit": "Salvar Controles de Acesso", "roles": "Funções", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "Edição Profissional Necessária", "licenseTierProfessionalRequiredDescription": "Esta funcionalidade só está disponível na Edição Profissional.", "actionGetOrg": "Obter Organização", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "Atualizar usuário Org", + "createOrgUser": "Criar usuário Org", "actionUpdateOrg": "Atualizar Organização", "actionUpdateUser": "Atualizar Usuário", "actionGetUser": "Obter Usuário", @@ -1240,7 +1240,7 @@ "newtUpdateAvailable": "Nova Atualização Disponível", "newtUpdateAvailableInfo": "Uma nova versão do Newt está disponível. Atualize para a versão mais recente para uma melhor experiência.", "domainPickerEnterDomain": "Domínio", - "domainPickerPlaceholder": "myapp.example.com", + "domainPickerPlaceholder": "myapp.exemplo.com", "domainPickerDescription": "Insira o domínio completo do recurso para ver as opções disponíveis.", "domainPickerDescriptionSaas": "Insira um domínio completo, subdomínio ou apenas um nome para ver as opções disponíveis", "domainPickerTabAll": "Todos", @@ -1503,6 +1503,19 @@ }, "internationaldomaindetected": "Domínio Internacional Detectado", "willbestoredas": "Será armazenado como:", - "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpGoogleDescription": "Provedor Google OAuth2/OIDC", + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Domínio fornecido", + "domainPickerFreeProvidedDomain": "Domínio fornecido grátis", + "domainPickerVerified": "Verificada", + "domainPickerUnverified": "Não verificado", + "domainPickerInvalidSubdomainStructure": "Este subdomínio contém caracteres ou estrutura inválidos. Ele será eliminado automaticamente quando você salvar.", + "domainPickerError": "ERRO", + "domainPickerErrorLoadDomains": "Falha ao carregar domínios da organização", + "domainPickerErrorCheckAvailability": "Não foi possível verificar a disponibilidade do domínio", + "domainPickerInvalidSubdomain": "Subdomínio inválido", + "domainPickerInvalidSubdomainRemoved": "A entrada \"{sub}\" foi removida porque ela não é válida.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" não pôde ser válido para {domain}.", + "domainPickerSubdomainSanitized": "Subdomínio banalizado", + "domainPickerSubdomainCorrected": "\"{sub}\" foi corrigido para \"{sanitized}\"" } diff --git a/messages/ru-RU.json b/messages/ru-RU.json index 7b8b2d67..37dad23f 100644 --- a/messages/ru-RU.json +++ b/messages/ru-RU.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "Произошла ошибка при добавлении пользователя в роль.", "userSaved": "Пользователь сохранён", "userSavedDescription": "Пользователь был обновлён.", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "Автоподбор", + "autoProvisionedDescription": "Разрешить автоматическое управление этим пользователем", "accessControlsDescription": "Управляйте тем, к чему этот пользователь может получить доступ и что делать в организации", "accessControlsSubmit": "Сохранить контроль доступа", "roles": "Роли", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "Требуется профессиональная версия", "licenseTierProfessionalRequiredDescription": "Эта функция доступна только в профессиональной версии.", "actionGetOrg": "Получить организацию", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "Обновить пользователя Org", + "createOrgUser": "Создать пользователя Org", "actionUpdateOrg": "Обновить организацию", "actionUpdateUser": "Обновить пользователя", "actionGetUser": "Получить пользователя", @@ -1503,6 +1503,19 @@ }, "internationaldomaindetected": "Обнаружен международный домен", "willbestoredas": "Будет храниться как:", - "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpGoogleDescription": "Google OAuth2/OIDC провайдер", + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "Домен предоставлен", + "domainPickerFreeProvidedDomain": "Бесплатный домен", + "domainPickerVerified": "Подтверждено", + "domainPickerUnverified": "Не подтверждено", + "domainPickerInvalidSubdomainStructure": "Этот поддомен содержит недопустимые символы или структуру. Он будет очищен автоматически при сохранении.", + "domainPickerError": "Ошибка", + "domainPickerErrorLoadDomains": "Не удалось загрузить домены организации", + "domainPickerErrorCheckAvailability": "Не удалось проверить доступность домена", + "domainPickerInvalidSubdomain": "Неверный поддомен", + "domainPickerInvalidSubdomainRemoved": "Ввод \"{sub}\" был удален, потому что он недействителен.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" не может быть действительным для {domain}.", + "domainPickerSubdomainSanitized": "Субдомен очищен", + "domainPickerSubdomainCorrected": "\"{sub}\" был исправлен на \"{sanitized}\"" } diff --git a/messages/tr-TR.json b/messages/tr-TR.json index 6008f2dc..dd3b66a4 100644 --- a/messages/tr-TR.json +++ b/messages/tr-TR.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "Kullanıcı role eklenirken bir hata oluştu.", "userSaved": "Kullanıcı kaydedildi", "userSavedDescription": "Kullanıcı güncellenmiştir.", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "Otomatik Sağlandı", + "autoProvisionedDescription": "Bu kullanıcının kimlik sağlayıcısı tarafından otomatik olarak yönetilmesine izin ver", "accessControlsDescription": "Bu kullanıcının organizasyonda neleri erişebileceğini ve yapabileceğini yönetin", "accessControlsSubmit": "Erişim Kontrollerini Kaydet", "roles": "Roller", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "Profesyonel Sürüme Gereklidir", "licenseTierProfessionalRequiredDescription": "Bu özellik yalnızca Professional Edition'da kullanılabilir.", "actionGetOrg": "Kuruluşu Al", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "Organizasyon Kullanıcısını Güncelle", + "createOrgUser": "Organizasyon Kullanıcısı Oluştur", "actionUpdateOrg": "Kuruluşu Güncelle", "actionUpdateUser": "Kullanıcıyı Güncelle", "actionGetUser": "Kullanıcıyı Getir", @@ -1503,6 +1503,19 @@ }, "internationaldomaindetected": "Uluslararası Alan Adı Tespit Edildi", "willbestoredas": "Şu şekilde depolanacak:", - "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpGoogleDescription": "Google OAuth2/OIDC sağlayıcısı", + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC sağlayıcısı", + "domainPickerProvidedDomain": "Sağlanan Alan Adı", + "domainPickerFreeProvidedDomain": "Ücretsiz Sağlanan Alan Adı", + "domainPickerVerified": "Doğrulandı", + "domainPickerUnverified": "Doğrulanmadı", + "domainPickerInvalidSubdomainStructure": "Bu alt alan adı geçersiz karakterler veya yapı içeriyor. Kaydettiğinizde otomatik olarak temizlenecektir.", + "domainPickerError": "Hata", + "domainPickerErrorLoadDomains": "Organizasyon alan adları yüklenemedi", + "domainPickerErrorCheckAvailability": "Alan adı kullanılabilirliği kontrol edilemedi", + "domainPickerInvalidSubdomain": "Geçersiz alt alan adı", + "domainPickerInvalidSubdomainRemoved": "Girdi \"{sub}\" geçersiz olduğu için kaldırıldı.", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" {domain} için geçerli yapılamadı.", + "domainPickerSubdomainSanitized": "Alt alan adı temizlendi", + "domainPickerSubdomainCorrected": "\"{sub}\" \"{sanitized}\" olarak düzeltildi" } diff --git a/messages/zh-CN.json b/messages/zh-CN.json index 25f09780..e40297fb 100644 --- a/messages/zh-CN.json +++ b/messages/zh-CN.json @@ -454,8 +454,8 @@ "accessRoleErrorAddDescription": "添加用户到角色时出错。", "userSaved": "用户已保存", "userSavedDescription": "用户已更新。", - "autoProvisioned": "Auto Provisioned", - "autoProvisionedDescription": "Allow this user to be automatically managed by identity provider", + "autoProvisioned": "自动设置", + "autoProvisionedDescription": "允许此用户由身份提供商自动管理", "accessControlsDescription": "管理此用户在组织中可以访问和做什么", "accessControlsSubmit": "保存访问控制", "roles": "角色", @@ -986,8 +986,8 @@ "licenseTierProfessionalRequired": "需要专业版", "licenseTierProfessionalRequiredDescription": "此功能仅在专业版可用。", "actionGetOrg": "获取组织", - "updateOrgUser": "Update Org User", - "createOrgUser": "Create Org User", + "updateOrgUser": "更新组织用户", + "createOrgUser": "创建组织用户", "actionUpdateOrg": "更新组织", "actionUpdateUser": "更新用户", "actionGetUser": "获取用户", @@ -1240,7 +1240,7 @@ "newtUpdateAvailable": "更新可用", "newtUpdateAvailableInfo": "新版本的 Newt 已可用。请更新到最新版本以获得最佳体验。", "domainPickerEnterDomain": "域名", - "domainPickerPlaceholder": "myapp.example.com", + "domainPickerPlaceholder": "example.com", "domainPickerDescription": "输入资源的完整域名以查看可用选项。", "domainPickerDescriptionSaas": "输入完整域名、子域或名称以查看可用选项。", "domainPickerTabAll": "所有", @@ -1503,6 +1503,19 @@ }, "internationaldomaindetected": "检测到国际域", "willbestoredas": "储存为:", - "idpGoogleDescription": "Google OAuth2/OIDC provider", - "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider" + "idpGoogleDescription": "Google OAuth2/OIDC 提供商", + "idpAzureDescription": "Microsoft Azure OAuth2/OIDC provider", + "domainPickerProvidedDomain": "提供的域", + "domainPickerFreeProvidedDomain": "免费提供的域", + "domainPickerVerified": "已验证", + "domainPickerUnverified": "未验证", + "domainPickerInvalidSubdomainStructure": "此子域包含无效的字符或结构。当您保存时,它将被自动清除。", + "domainPickerError": "错误", + "domainPickerErrorLoadDomains": "加载组织域名失败", + "domainPickerErrorCheckAvailability": "检查域可用性失败", + "domainPickerInvalidSubdomain": "无效的子域", + "domainPickerInvalidSubdomainRemoved": "输入 \"{sub}\" 已被移除,因为其无效。", + "domainPickerInvalidSubdomainCannotMakeValid": "\"{sub}\" 无法为 {domain} 变为有效。", + "domainPickerSubdomainSanitized": "子域已净化", + "domainPickerSubdomainCorrected": "\"{sub}\" 已被更正为 \"{sanitized}\"" } diff --git a/server/lib/consts.ts b/server/lib/consts.ts index b9afa792..30efc07e 100644 --- a/server/lib/consts.ts +++ b/server/lib/consts.ts @@ -2,7 +2,7 @@ import path from "path"; import { fileURLToPath } from "url"; // This is a placeholder value replaced by the build process -export const APP_VERSION = "1.9.0"; +export const APP_VERSION = "1.10.0"; export const __FILENAME = fileURLToPath(import.meta.url); export const __DIRNAME = path.dirname(__FILENAME); diff --git a/server/setup/migrationsPg.ts b/server/setup/migrationsPg.ts index 6b3f20b9..c5950e1d 100644 --- a/server/setup/migrationsPg.ts +++ b/server/setup/migrationsPg.ts @@ -9,6 +9,7 @@ import m1 from "./scriptsPg/1.6.0"; import m2 from "./scriptsPg/1.7.0"; import m3 from "./scriptsPg/1.8.0"; import m4 from "./scriptsPg/1.9.0"; +import m5 from "./scriptsPg/1.10.0"; // THIS CANNOT IMPORT ANYTHING FROM THE SERVER // EXCEPT FOR THE DATABASE AND THE SCHEMA @@ -18,7 +19,8 @@ const migrations = [ { version: "1.6.0", run: m1 }, { version: "1.7.0", run: m2 }, { version: "1.8.0", run: m3 }, - { version: "1.9.0", run: m4 } + { version: "1.9.0", run: m4 }, + { version: "1.10.0", run: m5 }, // Add new migrations here as they are created ] as { version: string; diff --git a/server/setup/migrationsSqlite.ts b/server/setup/migrationsSqlite.ts index 5b0850c8..79a7d0ab 100644 --- a/server/setup/migrationsSqlite.ts +++ b/server/setup/migrationsSqlite.ts @@ -26,6 +26,7 @@ import m21 from "./scriptsSqlite/1.6.0"; import m22 from "./scriptsSqlite/1.7.0"; import m23 from "./scriptsSqlite/1.8.0"; import m24 from "./scriptsSqlite/1.9.0"; +import m25 from "./scriptsSqlite/1.10.0"; // THIS CANNOT IMPORT ANYTHING FROM THE SERVER // EXCEPT FOR THE DATABASE AND THE SCHEMA @@ -51,6 +52,7 @@ const migrations = [ { version: "1.7.0", run: m22 }, { version: "1.8.0", run: m23 }, { version: "1.9.0", run: m24 }, + { version: "1.10.0", run: m25 }, // Add new migrations here as they are created ] as const; diff --git a/server/setup/scriptsPg/1.10.0.ts b/server/setup/scriptsPg/1.10.0.ts new file mode 100644 index 00000000..f33906cf --- /dev/null +++ b/server/setup/scriptsPg/1.10.0.ts @@ -0,0 +1,81 @@ +import { db } from "@server/db/pg/driver"; +import { sql } from "drizzle-orm"; +import { __DIRNAME, APP_PATH } from "@server/lib/consts"; +import { readFileSync } from "fs"; +import path, { join } from "path"; + +const version = "1.10.0"; + +export default async function migration() { + console.log(`Running setup script ${version}...`); + + try { + const resources = await db.execute(sql` + SELECT "resourceId" FROM "resources" WHERE "siteId" IS NOT NULL + `); + + await db.execute(sql`BEGIN`); + + await db.execute(sql`ALTER TABLE "exitNodes" ADD COLUMN "region" text;`); + + await db.execute(sql`ALTER TABLE "idpOidcConfig" ADD COLUMN "variant" text DEFAULT 'oidc' NOT NULL;`); + + await db.execute(sql`ALTER TABLE "resources" ADD COLUMN "niceId" text DEFAULT '' NOT NULL;`); + + await db.execute(sql`ALTER TABLE "userOrgs" ADD COLUMN "autoProvisioned" boolean DEFAULT false;`); + + const usedNiceIds: string[] = []; + + for (const resource of resources.rows) { + // Generate a unique name and ensure it's unique + let niceId = ""; + let loops = 0; + while (true) { + if (loops > 100) { + throw new Error("Could not generate a unique name"); + } + + niceId = generateName(); + if (!usedNiceIds.includes(niceId)) { + usedNiceIds.push(niceId); + break; + } + loops++; + } + await db.execute(sql` + UPDATE "resources" SET "niceId" = ${niceId} WHERE "resourceId" = ${resource.resourceId} + `); + } + + await db.execute(sql`COMMIT`); + console.log(`Migrated database`); + } catch (e) { + await db.execute(sql`ROLLBACK`); + console.log("Failed to migrate db:", e); + throw e; + } +} + +const dev = process.env.ENVIRONMENT !== "prod"; +let file; +if (!dev) { + file = join(__DIRNAME, "names.json"); +} else { + file = join("server/db/names.json"); +} +export const names = JSON.parse(readFileSync(file, "utf-8")); + +export function generateName(): string { + const name = ( + names.descriptors[ + Math.floor(Math.random() * names.descriptors.length) + ] + + "-" + + names.animals[Math.floor(Math.random() * names.animals.length)] + ) + .toLowerCase() + .replace(/\s/g, "-"); + + // clean out any non-alphanumeric characters except for dashes + return name.replace(/[^a-z0-9-]/g, ""); +} diff --git a/server/setup/scriptsSqlite/1.10.0.ts b/server/setup/scriptsSqlite/1.10.0.ts new file mode 100644 index 00000000..f5f6c3a3 --- /dev/null +++ b/server/setup/scriptsSqlite/1.10.0.ts @@ -0,0 +1,83 @@ +import { __DIRNAME, APP_PATH } from "@server/lib/consts"; +import Database from "better-sqlite3"; +import { readFileSync } from "fs"; +import path, { join } from "path"; + +const version = "1.10.0"; + +export default async function migration() { + console.log(`Running setup script ${version}...`); + + const location = path.join(APP_PATH, "db", "db.sqlite"); + const db = new Database(location); + + const resourceSiteMap = new Map(); + const firstSiteId: number = 1; + + try { + const resources = db + .prepare( + "SELECT resourceId FROM resources WHERE siteId IS NOT NULL" + ) + .all() as Array<{ resourceId: number; }>; + + db.transaction(() => { + db.exec(` + ALTER TABLE 'exitNodes' ADD 'region' text; + ALTER TABLE 'idpOidcConfig' ADD 'variant' text DEFAULT 'oidc' NOT NULL; + ALTER TABLE 'resources' ADD 'niceId' text DEFAULT '' NOT NULL; + ALTER TABLE 'userOrgs' ADD 'autoProvisioned' integer DEFAULT false; + `); // this diverges from the schema a bit because the schema does not have a default on niceId but was required for the migration and I dont think it will effect much down the line... + + const usedNiceIds: string[] = []; + + for (const resourceId of resources) { + // Generate a unique name and ensure it's unique + let niceId = ""; + let loops = 0; + while (true) { + if (loops > 100) { + throw new Error("Could not generate a unique name"); + } + + niceId = generateName(); + if (!usedNiceIds.includes(niceId)) { + usedNiceIds.push(niceId); + break; + } + loops++; + } + db.prepare(`UPDATE resources SET niceId = ? WHERE resourceId = ?`).run(niceId, resourceId.resourceId); + } + })(); + + console.log(`Migrated database`); + } catch (e) { + console.log("Failed to migrate db:", e); + throw e; + } +} + +const dev = process.env.ENVIRONMENT !== "prod"; +let file; +if (!dev) { + file = join(__DIRNAME, "names.json"); +} else { + file = join("server/db/names.json"); +} +export const names = JSON.parse(readFileSync(file, "utf-8")); + +export function generateName(): string { + const name = ( + names.descriptors[ + Math.floor(Math.random() * names.descriptors.length) + ] + + "-" + + names.animals[Math.floor(Math.random() * names.animals.length)] + ) + .toLowerCase() + .replace(/\s/g, "-"); + + // clean out any non-alphanumeric characters except for dashes + return name.replace(/[^a-z0-9-]/g, ""); +} diff --git a/src/app/[orgId]/settings/resources/create/page.tsx b/src/app/[orgId]/settings/resources/create/page.tsx index 5876cadf..16e2bf41 100644 --- a/src/app/[orgId]/settings/resources/create/page.tsx +++ b/src/app/[orgId]/settings/resources/create/page.tsx @@ -355,6 +355,8 @@ export default function Page() { } async function onSubmit() { + setShowSnippets(true); + router.refresh(); setCreateLoading(true); const baseData = baseForm.getValues(); @@ -1543,6 +1545,9 @@ export default function Page() {

{t("resourceAddEntrypoints")}

+

+ (Edit file: config/traefik/traefik_config.yml) +

{t("resourceExposePorts")} +

+ (Edit file: docker-compose.yml) +

void; cols?: number; + hideFreeDomain?: boolean; } export default function DomainPicker2({ orgId, onDomainChange, - cols = 2 + cols = 2, + hideFreeDomain = false }: DomainPicker2Props) { const { env } = useEnvContext(); const api = createApiClient({ env }); @@ -153,12 +155,12 @@ export default function DomainPicker2({ fullDomain: firstOrgDomain.baseDomain, baseDomain: firstOrgDomain.baseDomain }); - } else if (build === "saas" || build === "enterprise") { + } else if ((build === "saas" || build === "enterprise") && !hideFreeDomain) { // If no organization domains, select the provided domain option const domainOptionText = build === "enterprise" - ? "Provided Domain" - : "Free Provided Domain"; + ? t("domainPickerProvidedDomain") + : t("domainPickerFreeProvidedDomain"); const freeDomainOption: DomainOption = { id: "provided-search", domain: domainOptionText, @@ -171,8 +173,8 @@ export default function DomainPicker2({ console.error("Failed to load organization domains:", error); toast({ variant: "destructive", - title: "Error", - description: "Failed to load organization domains" + title: t("domainPickerError"), + description: t("domainPickerErrorLoadDomains") }); } finally { setLoadingDomains(false); @@ -180,7 +182,7 @@ export default function DomainPicker2({ }; loadOrganizationDomains(); - }, [orgId, api]); + }, [orgId, api, hideFreeDomain]); const checkAvailability = useCallback( async (input: string) => { @@ -202,8 +204,8 @@ export default function DomainPicker2({ setAvailableOptions([]); toast({ variant: "destructive", - title: "Error", - description: "Failed to check domain availability" + title: t("domainPickerError"), + description: t("domainPickerErrorCheckAvailability") }); } finally { setIsChecking(false); @@ -246,11 +248,11 @@ export default function DomainPicker2({ }); }); - if (build === "saas" || build === "enterprise") { + if ((build === "saas" || build === "enterprise") && !hideFreeDomain) { const domainOptionText = build === "enterprise" - ? "Provided Domain" - : "Free Provided Domain"; + ? t("domainPickerProvidedDomain") + : t("domainPickerFreeProvidedDomain"); options.push({ id: "provided-search", domain: domainOptionText, @@ -269,8 +271,8 @@ export default function DomainPicker2({ if (!sanitized) { toast({ variant: "destructive", - title: "Invalid subdomain", - description: `The input "${sub}" was removed because it's not valid.`, + title: t("domainPickerInvalidSubdomain"), + description: t("domainPickerInvalidSubdomainRemoved", { sub }), }); return ""; } @@ -283,16 +285,16 @@ export default function DomainPicker2({ if (!ok) { toast({ variant: "destructive", - title: "Invalid subdomain", - description: `"${sub}" could not be made valid for ${base.domain}.`, + title: t("domainPickerInvalidSubdomain"), + description: t("domainPickerInvalidSubdomainCannotMakeValid", { sub, domain: base.domain }), }); return ""; } if (sub !== sanitized) { toast({ - title: "Subdomain sanitized", - description: `"${sub}" was corrected to "${sanitized}"`, + title: t("domainPickerSubdomainSanitized"), + description: t("domainPickerSubdomainCorrected", { sub, sanitized }), }); } @@ -453,7 +455,7 @@ export default function DomainPicker2({ /> {showSubdomainInput && subdomainInput && !isValidSubdomainStructure(subdomainInput) && (

- This subdomain contains invalid characters or structure. It will be sanitized automatically when you save. + {t("domainPickerInvalidSubdomainStructure")}

)} {showSubdomainInput && !subdomainInput && ( @@ -555,8 +557,8 @@ export default function DomainPicker2({ {orgDomain.type.toUpperCase()}{" "} •{" "} {orgDomain.verified - ? "Verified" - : "Unverified"} + ? t("domainPickerVerified") + : t("domainPickerUnverified")} {(build === "saas" || - build === "enterprise") && ( + build === "enterprise") && !hideFreeDomain && ( )} )} {(build === "saas" || - build === "enterprise") && ( + build === "enterprise") && !hideFreeDomain && ( {build === "enterprise" - ? "Provided Domain" - : "Free Provided Domain"} + ? t("domainPickerProvidedDomain") + : t("domainPickerFreeProvidedDomain")} {t( @@ -771,4 +773,4 @@ function debounce any>( func(...args); }, wait); }; -} \ No newline at end of file +}