mirror of
https://github.com/fosrl/pangolin.git
synced 2025-07-22 19:55:37 +02:00
I18n auth (#23)
* New translation keys in en-US locale * New translation keys in de-DE locale * New translation keys in fr-FR locale * New translation keys in it-IT locale * New translation keys in pl-PL locale * New translation keys in pt-PT locale * New translation keys in tr-TR locale * Add translation keys in app/auth * Fix build --------- Co-authored-by: Lokowitz <marvinlokowitz@gmail.com>
This commit is contained in:
parent
d2d84be99a
commit
b8ed5ac1c5
23 changed files with 727 additions and 115 deletions
|
@ -133,7 +133,7 @@
|
|||
"shareAccessHint": "Jeder mit diesem Link kann auf die Ressource zugreifen. Teilen Sie sie mit Vorsicht.",
|
||||
"shareTokenUsage": "Zugriffstoken-Nutzung anzeigen",
|
||||
"createLink": "Link erstellen",
|
||||
"resourceNotFound": "Keine Ressourcen gefunden",
|
||||
"resourcesNotFound": "Keine Ressourcen gefunden",
|
||||
"resourceSearch": "Suche Ressourcen",
|
||||
"openMenu": "Menü öffnen",
|
||||
"resource": "Ressource",
|
||||
|
@ -802,5 +802,89 @@
|
|||
"redirectUrlAbout": "Über die Weiterleitungs-URL",
|
||||
"redirectUrlAboutDescription": "Dies ist die URL, zu der Benutzer nach der Authentifizierung weitergeleitet werden. Sie müssen diese URL in den Einstellungen Ihres Identitätsanbieters konfigurieren.",
|
||||
"key": "Schlüssel",
|
||||
"createdAt": "Erstellt am"
|
||||
"createdAt": "Erstellt am",
|
||||
"expiresAt": "Läuft ab am",
|
||||
"pangolinAuth": "Auth - Pangolin",
|
||||
"emailInvalid": "Ungültige E-Mail-Adresse",
|
||||
"verificationCodeLengthRequirements": "Ihr Verifizierungscode muss 8 Zeichen lang sein.",
|
||||
"errorOccurred": "Ein Fehler ist aufgetreten",
|
||||
"emailErrorVerify": "E-Mail konnte nicht verifiziert werden:",
|
||||
"emailVerified": "E-Mail erfolgreich verifiziert! Sie werden weitergeleitet...",
|
||||
"verificationCodeErrorResend": "Verifizierungscode konnte nicht erneut gesendet werden:",
|
||||
"verificationCodeResend": "Verifizierungscode erneut gesendet",
|
||||
"verificationCodeResendDescription": "Wir haben einen neuen Verifizierungscode an Ihre E-Mail-Adresse gesendet. Bitte prüfen Sie Ihren Posteingang.",
|
||||
"emailVerify": "E-Mail verifizieren",
|
||||
"emailVerifyDescription": "Geben Sie den an Ihre E-Mail-Adresse gesendeten Verifizierungscode ein.",
|
||||
"verificationCode": "Verifizierungscode",
|
||||
"verificationCodeEmailSent": "Wir haben einen Verifizierungscode an Ihre E-Mail-Adresse gesendet.",
|
||||
"emailVerifySubmit": "Absenden",
|
||||
"emailVerifyResendProgress": "Wird erneut gesendet...",
|
||||
"emailVerifyResend": "Keinen Code erhalten? Hier klicken zum erneuten Senden",
|
||||
"passwordNotMatch": "Passwörter stimmen nicht überein",
|
||||
"signupError": "Beim Registrieren ist ein Fehler aufgetreten",
|
||||
"pangolinLogoAlt": "Pangolin Logo",
|
||||
"inviteAlready": "Sieht aus, als wären Sie eingeladen worden!",
|
||||
"inviteAlreadyDescription": "Um die Einladung anzunehmen, müssen Sie sich einloggen oder ein Konto erstellen.",
|
||||
"signupQuestion": "Haben Sie bereits ein Konto?",
|
||||
"login": "Anmelden",
|
||||
"resourceNotFound": "Ressource nicht gefunden",
|
||||
"resourceNotFoundDescription": "Die Ressource, auf die Sie zugreifen möchten, existiert nicht.",
|
||||
"pincodeRequirementsLength": "PIN muss genau 6 Ziffern lang sein",
|
||||
"pincodeRequirementsChars": "PIN darf nur Zahlen enthalten",
|
||||
"passwordRequirementsLength": "Passwort muss mindestens 1 Zeichen lang sein",
|
||||
"otpEmailRequirementsLength": "OTP muss mindestens 1 Zeichen lang sein",
|
||||
"otpEmailSent": "OTP gesendet",
|
||||
"otpEmailSentDescription": "Ein OTP wurde an Ihre E-Mail gesendet",
|
||||
"otpEmailErrorAuthenticate": "Authentifizierung per E-Mail fehlgeschlagen",
|
||||
"pincodeErrorAuthenticate": "Authentifizierung per PIN fehlgeschlagen",
|
||||
"passwordErrorAuthenticate": "Authentifizierung per Passwort fehlgeschlagen",
|
||||
"poweredBy": "Bereitgestellt von",
|
||||
"authenticationRequired": "Authentifizierung erforderlich",
|
||||
"authenticationMethodChoose": "Wählen Sie Ihre bevorzugte Methode für den Zugriff auf {name}",
|
||||
"authenticationRequest": "Sie müssen sich authentifizieren, um auf {name} zuzugreifen",
|
||||
"user": "Benutzer",
|
||||
"pincodeInput": "6-stelliger PIN-Code",
|
||||
"pincodeSubmit": "Mit PIN anmelden",
|
||||
"passwordSubmit": "Mit Passwort anmelden",
|
||||
"otpEmailDescription": "Ein Einmalcode wird an diese E-Mail gesendet.",
|
||||
"otpEmailSend": "Einmalcode senden",
|
||||
"otpEmail": "Einmalpasswort (OTP)",
|
||||
"otpEmailSubmit": "OTP absenden",
|
||||
"backToEmail": "Zurück zur E-Mail",
|
||||
"noSupportKey": "Server läuft ohne Unterstützer-Schlüssel.<br/>Erwägen Sie, das Projekt zu unterstützen!",
|
||||
"accessDenied": "Zugriff verweigert",
|
||||
"accessDeniedDescription": "Sie haben keine Berechtigung, auf diese Ressource zuzugreifen. Falls dies ein Fehler ist, kontaktieren Sie bitte den Administrator.",
|
||||
"accessTokenError": "Fehler beim Prüfen des Zugriffstokens",
|
||||
"accessGranted": "Zugriff gewährt",
|
||||
"accessUrlInvalid": "Zugriffs-URL ungültig",
|
||||
"accessGrantedDescription": "Ihnen wurde Zugriff auf diese Ressource gewährt. Sie werden weitergeleitet...",
|
||||
"accessUrlInvalidDescription": "Diese geteilte Zugriffs-URL ist ungültig. Bitte kontaktieren Sie den Ressourceneigentümer für eine neue URL.",
|
||||
"tokenInvalid": "Ungültiger Token",
|
||||
"pincodeInvalid": "Ungültiger Code",
|
||||
"passwordErrorRequestReset": "Zurücksetzung konnte nicht angefordert werden:",
|
||||
"passwordErrorReset": "Passwort konnte nicht zurückgesetzt werden:",
|
||||
"passwordResetSuccess": "Passwort erfolgreich zurückgesetzt! Zurück zur Anmeldung...",
|
||||
"passwordReset": "Passwort zurücksetzen",
|
||||
"passwordResetDescription": "Folgen Sie den Schritten, um Ihr Passwort zurückzusetzen",
|
||||
"passwordResetSent": "Wir senden einen Code zum Zurücksetzen des Passworts an diese E-Mail-Adresse.",
|
||||
"passwordResetCode": "Reset-Code",
|
||||
"passwordResetCodeDescription": "Prüfen Sie Ihre E-Mail für den Reset-Code.",
|
||||
"passwordNew": "Neues Passwort",
|
||||
"passwordNewConfirm": "Neues Passwort bestätigen",
|
||||
"pincodeAuth": "Authentifizierungscode",
|
||||
"pincodeSubmit2": "Code absenden",
|
||||
"passwordResetSubmit": "Zurücksetzung anfordern",
|
||||
"passwordBack": "Zurück zum Passwort",
|
||||
"loginBack": "Zurück zur Anmeldung",
|
||||
"signup": "Registrieren",
|
||||
"loginStart": "Melden Sie sich an, um zu beginnen",
|
||||
"idpOidcTokenValidating": "OIDC-Token wird validiert",
|
||||
"idpOidcTokenResponse": "OIDC-Token-Antwort validieren",
|
||||
"idpErrorOidcTokenValidating": "Fehler beim Validieren des OIDC-Tokens",
|
||||
"idpConnectingTo": "Verbindung zu {name} wird hergestellt",
|
||||
"idpConnectingToDescription": "Ihre Identität wird überprüft",
|
||||
"idpConnectingToProcess": "Verbindung wird hergestellt...",
|
||||
"idpConnectingToFinished": "Verbunden",
|
||||
"idpErrorConnectingTo": "Es gab ein Problem bei der Verbindung zu {name}. Bitte kontaktieren Sie Ihren Administrator.",
|
||||
"idpErrorNotFound": "IdP nicht gefunden"
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
"shareAccessHint": "Anyone with this link can access the resource. Share it with care.",
|
||||
"shareTokenUsage": "See Access Token Usage",
|
||||
"createLink": "Create Link",
|
||||
"resourceNotFound": "No resources found",
|
||||
"resourcesNotFound": "No resources found",
|
||||
"resourceSearch": "Search resources",
|
||||
"openMenu": "Open menu",
|
||||
"resource": "Resource",
|
||||
|
@ -802,5 +802,89 @@
|
|||
"redirectUrlAbout": "About Redirect URL",
|
||||
"redirectUrlAboutDescription": "This is the URL to which users will be redirected after authentication. You need to configure this URL in your identity provider settings.",
|
||||
"key": "Key",
|
||||
"createdAt": "Created At"
|
||||
"createdAt": "Created At",
|
||||
"expiresAt": "Expires At",
|
||||
"pangolinAuth": "Auth - Pangolin",
|
||||
"emailInvalid": "Invalid email address",
|
||||
"verificationCodeLengthRequirements": "Your verification code must be 8 characters.",
|
||||
"errorOccurred": "An error occurred",
|
||||
"emailErrorVerify": "Failed to verify email:",
|
||||
"emailVerified": "Email successfully verified! Redirecting you...",
|
||||
"verificationCodeErrorResend": "Failed to resend verification code:",
|
||||
"verificationCodeResend": "Verification code resent",
|
||||
"verificationCodeResendDescription": "We've resent a verification code to your email address. Please check your inbox.",
|
||||
"emailVerify": "Verify Email",
|
||||
"emailVerifyDescription": "Enter the verification code sent to your email address.",
|
||||
"verificationCode": "Verification Code",
|
||||
"verificationCodeEmailSent": "We sent a verification code to your email address.",
|
||||
"emailVerifySubmit": "Submit",
|
||||
"emailVerifyResendProgress": "Resending...",
|
||||
"emailVerifyResend": "Didn't receive a code? Click here to resend",
|
||||
"passwordNotMatch": "Passwords do not match",
|
||||
"signupError": "An error occurred while signing up",
|
||||
"pangolinLogoAlt": "Pangolin Logo",
|
||||
"inviteAlready": "Looks like you've been invited!",
|
||||
"inviteAlreadyDescription": "To accept the invite, you must log in or create an account.",
|
||||
"signupQuestion": "Already have an account?",
|
||||
"login": "Log in",
|
||||
"resourceNotFound": "Resource Not Found",
|
||||
"resourceNotFoundDescription": "The resource you're trying to access does not exist.",
|
||||
"pincodeRequirementsLength": "PIN must be exactly 6 digits",
|
||||
"pincodeRequirementsChars": "PIN must only contain numbers",
|
||||
"passwordRequirementsLength": "Password must be at least 1 character long",
|
||||
"otpEmailRequirementsLength": "OTP must be at least 1 character long",
|
||||
"otpEmailSent": "OTP Sent",
|
||||
"otpEmailSentDescription": "An OTP has been sent to your email",
|
||||
"otpEmailErrorAuthenticate": "Failed to authenticate with email",
|
||||
"pincodeErrorAuthenticate": "Failed to authenticate with pincode",
|
||||
"passwordErrorAuthenticate": "Failed to authenticate with password",
|
||||
"poweredBy": "Powered by",
|
||||
"authenticationRequired": "Authentication Required",
|
||||
"authenticationMethodChoose": "Choose your preferred method to access {name}",
|
||||
"authenticationRequest": "You must authenticate to access {name}",
|
||||
"user": "User",
|
||||
"pincodeInput": "6-digit PIN Code",
|
||||
"pincodeSubmit": "Log in with PIN",
|
||||
"passwordSubmit": "Log In with Password",
|
||||
"otpEmailDescription": "A one-time code will be sent to this email.",
|
||||
"otpEmailSend": "Send One-time Code",
|
||||
"otpEmail": "One-Time Password (OTP)",
|
||||
"otpEmailSubmit": "Submit OTP",
|
||||
"backToEmail": "Back to Email",
|
||||
"noSupportKey": "Server is running without a supporter key.<br/>Consider supporting the project!",
|
||||
"accessDenied": "Access Denied",
|
||||
"accessDeniedDescription": "You're not allowed to access this resource. If this is a mistake, please contact the administrator.",
|
||||
"accessTokenError": "Error checking access token",
|
||||
"accessGranted": "Access Granted",
|
||||
"accessUrlInvalid": "Access URL Invalid",
|
||||
"accessGrantedDescription": "You have been granted access to this resource. Redirecting you...",
|
||||
"accessUrlInvalidDescription": "This shared access URL is invalid. Please contact the resource owner for a new URL.",
|
||||
"tokenInvalid": "Invalid token",
|
||||
"pincodeInvalid": "Invalid code",
|
||||
"passwordErrorRequestReset": "Failed to request reset:",
|
||||
"passwordErrorReset": "Failed to reset password:",
|
||||
"passwordResetSuccess": "Password reset successfully! Back to log in...",
|
||||
"passwordReset": "Reset Password",
|
||||
"passwordResetDescription": "Follow the steps to reset your password",
|
||||
"passwordResetSent": "We'll send a password reset code to this email address.",
|
||||
"passwordResetCode": "Reset Code",
|
||||
"passwordResetCodeDescription": "Check your email for the reset code.",
|
||||
"passwordNew": "New Password",
|
||||
"passwordNewConfirm": "Confirm New Password",
|
||||
"pincodeAuth": "Authenticator Code",
|
||||
"pincodeSubmit2": "Submit Code",
|
||||
"passwordResetSubmit": "Request Reset",
|
||||
"passwordBack": "Back to Password",
|
||||
"loginBack": "Go back to log in",
|
||||
"signup": "Sign up",
|
||||
"loginStart": "Log in to get started",
|
||||
"idpOidcTokenValidating": "Validating OIDC token",
|
||||
"idpOidcTokenResponse": "Validate OIDC token response",
|
||||
"idpErrorOidcTokenValidating": "Error validating OIDC token",
|
||||
"idpConnectingTo": "Connecting to {name}",
|
||||
"idpConnectingToDescription": "Validating your identity",
|
||||
"idpConnectingToProcess": "Connecting...",
|
||||
"idpConnectingToFinished": "Connected",
|
||||
"idpErrorConnectingTo": "There was a problem connecting to {name}. Please contact your administrator.",
|
||||
"idpErrorNotFound": "IdP not found"
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
"shareAccessHint": "N'importe qui avec ce lien peut accéder à la ressource. Partagez-le avec soin.",
|
||||
"shareTokenUsage": "Voir Utilisation du jeton d'accès",
|
||||
"createLink": "Créer un lien",
|
||||
"resourceNotFound": "Aucune ressource trouvée",
|
||||
"resourcesNotFound": "Aucune ressource trouvée",
|
||||
"resourceSearch": "Rechercher des ressources",
|
||||
"openMenu": "Ouvrir le menu",
|
||||
"resource": "Ressource",
|
||||
|
@ -802,5 +802,89 @@
|
|||
"redirectUrlAbout": "À propos de l'URL de redirection",
|
||||
"redirectUrlAboutDescription": "C'est l'URL vers laquelle les utilisateurs seront redirigés après l'authentification. Vous devez configurer cette URL dans les paramètres de votre fournisseur d'identité.",
|
||||
"key": "Clé",
|
||||
"createdAt": "Créé le"
|
||||
"createdAt": "Créé le",
|
||||
"expiresAt": "Expire le",
|
||||
"pangolinAuth": "Auth - Pangolin",
|
||||
"emailInvalid": "Adresse e-mail invalide",
|
||||
"verificationCodeLengthRequirements": "Votre code de vérification doit comporter 8 caractères.",
|
||||
"errorOccurred": "Une erreur s'est produite",
|
||||
"emailErrorVerify": "Échec de la vérification de l'e-mail :",
|
||||
"emailVerified": "E-mail vérifié avec succès ! Redirection...",
|
||||
"verificationCodeErrorResend": "Échec du renvoi du code de vérification :",
|
||||
"verificationCodeResend": "Code de vérification renvoyé",
|
||||
"verificationCodeResendDescription": "Nous avons renvoyé un code de vérification à votre adresse e-mail. Veuillez vérifier votre boîte de réception.",
|
||||
"emailVerify": "Vérifier l'e-mail",
|
||||
"emailVerifyDescription": "Entrez le code de vérification envoyé à votre adresse e-mail.",
|
||||
"verificationCode": "Code de vérification",
|
||||
"verificationCodeEmailSent": "Nous avons envoyé un code de vérification à votre adresse e-mail.",
|
||||
"emailVerifySubmit": "Soumettre",
|
||||
"emailVerifyResendProgress": "Renvoi en cours...",
|
||||
"emailVerifyResend": "Vous n'avez pas reçu de code ? Cliquez ici pour renvoyer",
|
||||
"passwordNotMatch": "Les mots de passe ne correspondent pas",
|
||||
"signupError": "Une erreur s'est produite lors de l'inscription",
|
||||
"pangolinLogoAlt": "Logo Pangolin",
|
||||
"inviteAlready": "On dirait que vous avez été invité !",
|
||||
"inviteAlreadyDescription": "Pour accepter l'invitation, vous devez vous connecter ou créer un compte.",
|
||||
"signupQuestion": "Vous avez déjà un compte ?",
|
||||
"login": "Se connecter",
|
||||
"resourceNotFound": "Ressource introuvable",
|
||||
"resourceNotFoundDescription": "La ressource que vous essayez d'accéder n'existe pas.",
|
||||
"pincodeRequirementsLength": "Le code PIN doit comporter exactement 6 chiffres",
|
||||
"pincodeRequirementsChars": "Le code PIN ne doit contenir que des chiffres",
|
||||
"passwordRequirementsLength": "Le mot de passe doit comporter au moins 1 caractère",
|
||||
"otpEmailRequirementsLength": "L'OTP doit comporter au moins 1 caractère",
|
||||
"otpEmailSent": "OTP envoyé",
|
||||
"otpEmailSentDescription": "Un OTP a été envoyé à votre e-mail",
|
||||
"otpEmailErrorAuthenticate": "Échec de l'authentification par e-mail",
|
||||
"pincodeErrorAuthenticate": "Échec de l'authentification avec le code PIN",
|
||||
"passwordErrorAuthenticate": "Échec de l'authentification avec le mot de passe",
|
||||
"poweredBy": "Propulsé par",
|
||||
"authenticationRequired": "Authentification requise",
|
||||
"authenticationMethodChoose": "Choisissez votre méthode préférée pour accéder à {name}",
|
||||
"authenticationRequest": "Vous devez vous authentifier pour accéder à {name}",
|
||||
"user": "Utilisateur",
|
||||
"pincodeInput": "Code PIN à 6 chiffres",
|
||||
"pincodeSubmit": "Se connecter avec le PIN",
|
||||
"passwordSubmit": "Se connecter avec le mot de passe",
|
||||
"otpEmailDescription": "Un code à usage unique sera envoyé à cet e-mail.",
|
||||
"otpEmailSend": "Envoyer le code à usage unique",
|
||||
"otpEmail": "Mot de passe à usage unique (OTP)",
|
||||
"otpEmailSubmit": "Soumettre l'OTP",
|
||||
"backToEmail": "Retour à l'e-mail",
|
||||
"noSupportKey": "Le serveur fonctionne sans clé de support.<br/>Envisagez de soutenir le projet !",
|
||||
"accessDenied": "Accès refusé",
|
||||
"accessDeniedDescription": "Vous n'êtes pas autorisé à accéder à cette ressource. Si c'est une erreur, veuillez contacter l'administrateur.",
|
||||
"accessTokenError": "Erreur lors de la vérification du jeton d'accès",
|
||||
"accessGranted": "Accès accordé",
|
||||
"accessUrlInvalid": "URL d'accès invalide",
|
||||
"accessGrantedDescription": "L'accès à cette ressource vous a été accordé. Redirection...",
|
||||
"accessUrlInvalidDescription": "Cette URL d'accès partagé n'est pas valide. Veuillez contacter le propriétaire de la ressource pour obtenir une nouvelle URL.",
|
||||
"tokenInvalid": "Jeton invalide",
|
||||
"pincodeInvalid": "Code invalide",
|
||||
"passwordErrorRequestReset": "Échec de la demande de réinitialisation :",
|
||||
"passwordErrorReset": "Échec de la réinitialisation du mot de passe :",
|
||||
"passwordResetSuccess": "Mot de passe réinitialisé avec succès ! Retour à la connexion...",
|
||||
"passwordReset": "Réinitialiser le mot de passe",
|
||||
"passwordResetDescription": "Suivez les étapes pour réinitialiser votre mot de passe",
|
||||
"passwordResetSent": "Nous allons envoyer un code de réinitialisation à cette adresse e-mail.",
|
||||
"passwordResetCode": "Code de réinitialisation",
|
||||
"passwordResetCodeDescription": "Vérifiez votre e-mail pour le code de réinitialisation.",
|
||||
"passwordNew": "Nouveau mot de passe",
|
||||
"passwordNewConfirm": "Confirmer le nouveau mot de passe",
|
||||
"pincodeAuth": "Code d'authentification",
|
||||
"pincodeSubmit2": "Soumettre le code",
|
||||
"passwordResetSubmit": "Demander la réinitialisation",
|
||||
"passwordBack": "Retour au mot de passe",
|
||||
"loginBack": "Retour à la connexion",
|
||||
"signup": "S'inscrire",
|
||||
"loginStart": "Connectez-vous pour commencer",
|
||||
"idpOidcTokenValidating": "Validation du jeton OIDC",
|
||||
"idpOidcTokenResponse": "Valider la réponse du jeton OIDC",
|
||||
"idpErrorOidcTokenValidating": "Erreur lors de la validation du jeton OIDC",
|
||||
"idpConnectingTo": "Connexion à {name}",
|
||||
"idpConnectingToDescription": "Validation de votre identité",
|
||||
"idpConnectingToProcess": "Connexion...",
|
||||
"idpConnectingToFinished": "Connecté",
|
||||
"idpErrorConnectingTo": "Un problème est survenu lors de la connexion à {name}. Veuillez contacter votre administrateur.",
|
||||
"idpErrorNotFound": "IdP introuvable"
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
"shareAccessHint": "Chiunque abbia questo link può accedere alla risorsa. Condividilo con cura.",
|
||||
"shareTokenUsage": "Vedi Utilizzo Token Di Accesso",
|
||||
"createLink": "Crea Collegamento",
|
||||
"resourceNotFound": "Nessuna risorsa trovata",
|
||||
"resourcesNotFound": "Nessuna risorsa trovata",
|
||||
"resourceSearch": "Cerca risorse",
|
||||
"openMenu": "Apri menu",
|
||||
"resource": "Risorsa",
|
||||
|
@ -802,5 +802,89 @@
|
|||
"redirectUrlAbout": "Informazioni sull'URL di Reindirizzamento",
|
||||
"redirectUrlAboutDescription": "Questo è l'URL a cui gli utenti verranno reindirizzati dopo l'autenticazione. Devi configurare questo URL nelle impostazioni del tuo provider di identità.",
|
||||
"key": "Chiave",
|
||||
"createdAt": "Creato Il"
|
||||
"createdAt": "Creato Il",
|
||||
"expiresAt": "Scade Il",
|
||||
"pangolinAuth": "Auth - Pangolin",
|
||||
"emailInvalid": "Indirizzo email non valido",
|
||||
"verificationCodeLengthRequirements": "Il tuo codice di verifica deve essere di 8 caratteri.",
|
||||
"errorOccurred": "Si è verificato un errore",
|
||||
"emailErrorVerify": "Impossibile verificare l'email:",
|
||||
"emailVerified": "Email verificata con successo! Reindirizzamento in corso...",
|
||||
"verificationCodeErrorResend": "Impossibile reinviare il codice di verifica:",
|
||||
"verificationCodeResend": "Codice di verifica reinviato",
|
||||
"verificationCodeResendDescription": "Abbiamo reinviato un codice di verifica al tuo indirizzo email. Controlla la tua casella di posta.",
|
||||
"emailVerify": "Verifica Email",
|
||||
"emailVerifyDescription": "Inserisci il codice di verifica inviato al tuo indirizzo email.",
|
||||
"verificationCode": "Codice di Verifica",
|
||||
"verificationCodeEmailSent": "Abbiamo inviato un codice di verifica al tuo indirizzo email.",
|
||||
"emailVerifySubmit": "Invia",
|
||||
"emailVerifyResendProgress": "Reinvio in corso...",
|
||||
"emailVerifyResend": "Non hai ricevuto il codice? Clicca qui per reinviare",
|
||||
"passwordNotMatch": "Le password non coincidono",
|
||||
"signupError": "Si è verificato un errore durante la registrazione",
|
||||
"pangolinLogoAlt": "Logo Pangolin",
|
||||
"inviteAlready": "Sembra che sei stato invitato!",
|
||||
"inviteAlreadyDescription": "Per accettare l'invito, devi accedere o creare un account.",
|
||||
"signupQuestion": "Hai già un account?",
|
||||
"login": "Accedi",
|
||||
"resourceNotFound": "Risorsa Non Trovata",
|
||||
"resourceNotFoundDescription": "La risorsa che stai cercando di accedere non esiste.",
|
||||
"pincodeRequirementsLength": "Il PIN deve essere esattamente di 6 cifre",
|
||||
"pincodeRequirementsChars": "Il PIN deve contenere solo numeri",
|
||||
"passwordRequirementsLength": "La password deve essere lunga almeno 1 carattere",
|
||||
"otpEmailRequirementsLength": "L'OTP deve essere lungo almeno 1 carattere",
|
||||
"otpEmailSent": "OTP Inviato",
|
||||
"otpEmailSentDescription": "Un OTP è stato inviato alla tua email",
|
||||
"otpEmailErrorAuthenticate": "Impossibile autenticare con l'email",
|
||||
"pincodeErrorAuthenticate": "Impossibile autenticare con il codice PIN",
|
||||
"passwordErrorAuthenticate": "Impossibile autenticare con la password",
|
||||
"poweredBy": "Offerto da",
|
||||
"authenticationRequired": "Autenticazione Richiesta",
|
||||
"authenticationMethodChoose": "Scegli il tuo metodo preferito per accedere a {name}",
|
||||
"authenticationRequest": "Devi autenticarti per accedere a {name}",
|
||||
"user": "Utente",
|
||||
"pincodeInput": "Codice PIN a 6 cifre",
|
||||
"pincodeSubmit": "Accedi con PIN",
|
||||
"passwordSubmit": "Accedi con Password",
|
||||
"otpEmailDescription": "Un codice usa e getta verrà inviato a questa email.",
|
||||
"otpEmailSend": "Invia Codice Usa e Getta",
|
||||
"otpEmail": "Password Usa e Getta (OTP)",
|
||||
"otpEmailSubmit": "Invia OTP",
|
||||
"backToEmail": "Torna all'Email",
|
||||
"noSupportKey": "Il server è in esecuzione senza una chiave di supporto.<br/>Considera di supportare il progetto!",
|
||||
"accessDenied": "Accesso Negato",
|
||||
"accessDeniedDescription": "Non sei autorizzato ad accedere a questa risorsa. Se ritieni che sia un errore, contatta l'amministratore.",
|
||||
"accessTokenError": "Errore nel controllo del token di accesso",
|
||||
"accessGranted": "Accesso Concesso",
|
||||
"accessUrlInvalid": "URL di Accesso Non Valido",
|
||||
"accessGrantedDescription": "Ti è stato concesso l'accesso a questa risorsa. Reindirizzamento in corso...",
|
||||
"accessUrlInvalidDescription": "Questo URL di accesso condiviso non è valido. Contatta il proprietario della risorsa per un nuovo URL.",
|
||||
"tokenInvalid": "Token non valido",
|
||||
"pincodeInvalid": "Codice non valido",
|
||||
"passwordErrorRequestReset": "Impossibile richiedere il reset:",
|
||||
"passwordErrorReset": "Impossibile reimpostare la password:",
|
||||
"passwordResetSuccess": "Password reimpostata con successo! Torna al login...",
|
||||
"passwordReset": "Reimposta Password",
|
||||
"passwordResetDescription": "Segui i passaggi per reimpostare la tua password",
|
||||
"passwordResetSent": "Invieremo un codice di reset della password a questo indirizzo email.",
|
||||
"passwordResetCode": "Codice di Reset",
|
||||
"passwordResetCodeDescription": "Controlla la tua email per il codice di reset.",
|
||||
"passwordNew": "Nuova Password",
|
||||
"passwordNewConfirm": "Conferma Nuova Password",
|
||||
"pincodeAuth": "Codice Autenticatore",
|
||||
"pincodeSubmit2": "Invia Codice",
|
||||
"passwordResetSubmit": "Richiedi Reset",
|
||||
"passwordBack": "Torna alla Password",
|
||||
"loginBack": "Torna al login",
|
||||
"signup": "Registrati",
|
||||
"loginStart": "Accedi per iniziare",
|
||||
"idpOidcTokenValidating": "Convalida token OIDC",
|
||||
"idpOidcTokenResponse": "Convalida risposta token OIDC",
|
||||
"idpErrorOidcTokenValidating": "Errore nella convalida del token OIDC",
|
||||
"idpConnectingTo": "Connessione a {name}",
|
||||
"idpConnectingToDescription": "Convalida della tua identità",
|
||||
"idpConnectingToProcess": "Connessione in corso...",
|
||||
"idpConnectingToFinished": "Connesso",
|
||||
"idpErrorConnectingTo": "Si è verificato un problema durante la connessione a {name}. Contatta il tuo amministratore.",
|
||||
"idpErrorNotFound": "IdP non trovato"
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
"shareAccessHint": "Każdy z tym linkiem może uzyskać dostęp do zasobu. Podziel się nim ostrożnie.",
|
||||
"shareTokenUsage": "Zobacz użycie tokenu dostępu",
|
||||
"createLink": "Utwórz link",
|
||||
"resourceNotFound": "Nie znaleziono zasobów",
|
||||
"resourcesNotFound": "Nie znaleziono zasobów",
|
||||
"resourceSearch": "Szukaj zasobów",
|
||||
"openMenu": "Otwórz menu",
|
||||
"resource": "Zasoby",
|
||||
|
@ -802,5 +802,89 @@
|
|||
"redirectUrlAbout": "O URL przekierowania",
|
||||
"redirectUrlAboutDescription": "Jest to URL, na który użytkownicy zostaną przekierowani po uwierzytelnieniu. Musisz skonfigurować ten URL w ustawieniach swojego dostawcy tożsamości.",
|
||||
"key": "Klucz",
|
||||
"createdAt": "Utworzono"
|
||||
"createdAt": "Utworzono",
|
||||
"expiresAt": "Wygasa w dniu",
|
||||
"pangolinAuth": "Autoryzacja - Pangolin",
|
||||
"emailInvalid": "Nieprawidłowy adres e-mail",
|
||||
"verificationCodeLengthRequirements": "Twój kod weryfikacyjny musi mieć 8 znaków.",
|
||||
"errorOccurred": "Wystąpił błąd",
|
||||
"emailErrorVerify": "Nie udało się zweryfikować adresu e-mail:",
|
||||
"emailVerified": "E-mail został pomyślnie zweryfikowany! Przekierowywanie...",
|
||||
"verificationCodeErrorResend": "Nie udało się ponownie wysłać kodu weryfikacyjnego:",
|
||||
"verificationCodeResend": "Kod weryfikacyjny wysłany ponownie",
|
||||
"verificationCodeResendDescription": "Wysłaliśmy ponownie kod weryfikacyjny na Twój adres e-mail. Sprawdź swoją skrzynkę odbiorczą.",
|
||||
"emailVerify": "Zweryfikuj e-mail",
|
||||
"emailVerifyDescription": "Wprowadź kod weryfikacyjny wysłany na Twój adres e-mail.",
|
||||
"verificationCode": "Kod weryfikacyjny",
|
||||
"verificationCodeEmailSent": "Wysłaliśmy kod weryfikacyjny na Twój adres e-mail.",
|
||||
"emailVerifySubmit": "Wyślij",
|
||||
"emailVerifyResendProgress": "Ponowne wysyłanie...",
|
||||
"emailVerifyResend": "Nie otrzymałeś kodu? Kliknij tutaj, aby wysłać ponownie",
|
||||
"passwordNotMatch": "Hasła nie są zgodne",
|
||||
"signupError": "Wystąpił błąd podczas rejestracji",
|
||||
"pangolinLogoAlt": "Logo Pangolin",
|
||||
"inviteAlready": "Wygląda na to, że zostałeś już zaproszony!",
|
||||
"inviteAlreadyDescription": "Aby zaakceptować zaproszenie, musisz się zalogować lub utworzyć konto.",
|
||||
"signupQuestion": "Masz już konto?",
|
||||
"login": "Zaloguj się",
|
||||
"resourceNotFound": "Nie znaleziono zasobu",
|
||||
"resourceNotFoundDescription": "Zasób, do którego próbujesz uzyskać dostęp, nie istnieje.",
|
||||
"pincodeRequirementsLength": "PIN musi składać się dokładnie z 6 cyfr",
|
||||
"pincodeRequirementsChars": "PIN może zawierać tylko cyfry",
|
||||
"passwordRequirementsLength": "Hasło musi mieć co najmniej 1 znak",
|
||||
"otpEmailRequirementsLength": "Kod jednorazowy musi mieć co najmniej 1 znak",
|
||||
"otpEmailSent": "Kod jednorazowy wysłany",
|
||||
"otpEmailSentDescription": "Kod jednorazowy został wysłany na Twój e-mail",
|
||||
"otpEmailErrorAuthenticate": "Nie udało się uwierzytelnić za pomocą e-maila",
|
||||
"pincodeErrorAuthenticate": "Nie udało się uwierzytelnić za pomocą kodu PIN",
|
||||
"passwordErrorAuthenticate": "Nie udało się uwierzytelnić za pomocą hasła",
|
||||
"poweredBy": "Obsługiwane przez",
|
||||
"authenticationRequired": "Wymagane uwierzytelnienie",
|
||||
"authenticationMethodChoose": "Wybierz preferowaną metodę dostępu do {name}",
|
||||
"authenticationRequest": "Musisz się uwierzytelnić, aby uzyskać dostęp do {name}",
|
||||
"user": "Użytkownik",
|
||||
"pincodeInput": "6-cyfrowy kod PIN",
|
||||
"pincodeSubmit": "Zaloguj się kodem PIN",
|
||||
"passwordSubmit": "Zaloguj się hasłem",
|
||||
"otpEmailDescription": "Kod jednorazowy zostanie wysłany na ten adres e-mail.",
|
||||
"otpEmailSend": "Wyślij kod jednorazowy",
|
||||
"otpEmail": "Hasło jednorazowe (OTP)",
|
||||
"otpEmailSubmit": "Wyślij OTP",
|
||||
"backToEmail": "Powrót do e-maila",
|
||||
"noSupportKey": "Serwer działa bez klucza wspierającego.<br/>Rozważ wsparcie projektu!",
|
||||
"accessDenied": "Odmowa dostępu",
|
||||
"accessDeniedDescription": "Nie masz uprawnień dostępu do tego zasobu. Jeśli to pomyłka, skontaktuj się z administratorem.",
|
||||
"accessTokenError": "Błąd sprawdzania tokena dostępu",
|
||||
"accessGranted": "Dostęp przyznany",
|
||||
"accessUrlInvalid": "Nieprawidłowy URL dostępu",
|
||||
"accessGrantedDescription": "Otrzymałeś dostęp do tego zasobu. Przekierowywanie...",
|
||||
"accessUrlInvalidDescription": "Ten udostępniony URL dostępu jest nieprawidłowy. Skontaktuj się z właścicielem zasobu, aby otrzymać nowy URL.",
|
||||
"tokenInvalid": "Nieprawidłowy token",
|
||||
"pincodeInvalid": "Nieprawidłowy kod",
|
||||
"passwordErrorRequestReset": "Nie udało się zażądać resetowania:",
|
||||
"passwordErrorReset": "Nie udało się zresetować hasła:",
|
||||
"passwordResetSuccess": "Hasło zostało pomyślnie zresetowane! Powrót do logowania...",
|
||||
"passwordReset": "Zresetuj hasło",
|
||||
"passwordResetDescription": "Wykonaj kroki, aby zresetować hasło",
|
||||
"passwordResetSent": "Wyślemy kod resetowania hasła na ten adres e-mail.",
|
||||
"passwordResetCode": "Kod resetowania",
|
||||
"passwordResetCodeDescription": "Sprawdź swój e-mail, aby znaleźć kod resetowania.",
|
||||
"passwordNew": "Nowe hasło",
|
||||
"passwordNewConfirm": "Potwierdź nowe hasło",
|
||||
"pincodeAuth": "Kod uwierzytelniający",
|
||||
"pincodeSubmit2": "Wyślij kod",
|
||||
"passwordResetSubmit": "Zażądaj resetowania",
|
||||
"passwordBack": "Powrót do hasła",
|
||||
"loginBack": "Wróć do logowania",
|
||||
"signup": "Zarejestruj się",
|
||||
"loginStart": "Zaloguj się, aby rozpocząć",
|
||||
"idpOidcTokenValidating": "Walidacja tokena OIDC",
|
||||
"idpOidcTokenResponse": "Zweryfikuj odpowiedź tokena OIDC",
|
||||
"idpErrorOidcTokenValidating": "Błąd walidacji tokena OIDC",
|
||||
"idpConnectingTo": "Łączenie z {name}",
|
||||
"idpConnectingToDescription": "Weryfikacja tożsamości",
|
||||
"idpConnectingToProcess": "Łączenie...",
|
||||
"idpConnectingToFinished": "Połączono",
|
||||
"idpErrorConnectingTo": "Wystąpił problem z połączeniem z {name}. Skontaktuj się z administratorem.",
|
||||
"idpErrorNotFound": "Nie znaleziono IdP"
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
"shareAccessHint": "Qualquer um com este link pode acessar o recurso. Compartilhe com cuidado.",
|
||||
"shareTokenUsage": "Ver Uso do Token de Acesso",
|
||||
"createLink": "Criar Link",
|
||||
"resourceNotFound": "Nenhum recurso encontrado",
|
||||
"resourcesNotFound": "Nenhum recurso encontrado",
|
||||
"resourceSearch": "Recursos de pesquisa",
|
||||
"openMenu": "Abrir menu",
|
||||
"resource": "Recurso",
|
||||
|
@ -802,5 +802,89 @@
|
|||
"redirectUrlAbout": "Sobre o URL de Redirecionamento",
|
||||
"redirectUrlAboutDescription": "Este é o URL para o qual os utilizadores serão redirecionados após a autenticação. Precisa configurar este URL nas configurações do seu provedor de identidade.",
|
||||
"key": "Chave",
|
||||
"createdAt": "Criado Em"
|
||||
"createdAt": "Criado Em",
|
||||
"expiresAt": "Expira em",
|
||||
"pangolinAuth": "Autenticação - Pangolin",
|
||||
"emailInvalid": "Endereço de email inválido",
|
||||
"verificationCodeLengthRequirements": "O seu código de verificação deve ter 8 caracteres.",
|
||||
"errorOccurred": "Ocorreu um erro",
|
||||
"emailErrorVerify": "Falha ao verificar o email:",
|
||||
"emailVerified": "Email verificado com sucesso! Redirecionando...",
|
||||
"verificationCodeErrorResend": "Falha ao reenviar o código de verificação:",
|
||||
"verificationCodeResend": "Código de verificação reenviado",
|
||||
"verificationCodeResendDescription": "Reenviámos um código de verificação para o seu email. Por favor, verifique a sua caixa de entrada.",
|
||||
"emailVerify": "Verificar Email",
|
||||
"emailVerifyDescription": "Insira o código de verificação enviado para o seu email.",
|
||||
"verificationCode": "Código de Verificação",
|
||||
"verificationCodeEmailSent": "Enviámos um código de verificação para o seu email.",
|
||||
"emailVerifySubmit": "Submeter",
|
||||
"emailVerifyResendProgress": "A reenviar...",
|
||||
"emailVerifyResend": "Não recebeu um código? Clique aqui para reenviar",
|
||||
"passwordNotMatch": "As palavras-passe não correspondem",
|
||||
"signupError": "Ocorreu um erro durante o registo",
|
||||
"pangolinLogoAlt": "Logótipo Pangolin",
|
||||
"inviteAlready": "Parece que já foi convidado!",
|
||||
"inviteAlreadyDescription": "Para aceitar o convite, deve iniciar sessão ou criar uma conta.",
|
||||
"signupQuestion": "Já tem uma conta?",
|
||||
"login": "Iniciar sessão",
|
||||
"resourceNotFound": "Recurso Não Encontrado",
|
||||
"resourceNotFoundDescription": "O recurso que está a tentar aceder não existe.",
|
||||
"pincodeRequirementsLength": "O PIN deve ter exatamente 6 dígitos",
|
||||
"pincodeRequirementsChars": "O PIN deve conter apenas números",
|
||||
"passwordRequirementsLength": "A palavra-passe deve ter pelo menos 1 caractere",
|
||||
"otpEmailRequirementsLength": "O OTP deve ter pelo menos 1 caractere",
|
||||
"otpEmailSent": "OTP Enviado",
|
||||
"otpEmailSentDescription": "Um OTP foi enviado para o seu email",
|
||||
"otpEmailErrorAuthenticate": "Falha na autenticação por email",
|
||||
"pincodeErrorAuthenticate": "Falha na autenticação com PIN",
|
||||
"passwordErrorAuthenticate": "Falha na autenticação com palavra-passe",
|
||||
"poweredBy": "Desenvolvido por",
|
||||
"authenticationRequired": "Autenticação Necessária",
|
||||
"authenticationMethodChoose": "Escolha o seu método preferido para aceder a {name}",
|
||||
"authenticationRequest": "Deve autenticar-se para aceder a {name}",
|
||||
"user": "Utilizador",
|
||||
"pincodeInput": "Código PIN de 6 dígitos",
|
||||
"pincodeSubmit": "Iniciar sessão com PIN",
|
||||
"passwordSubmit": "Iniciar Sessão com Palavra-passe",
|
||||
"otpEmailDescription": "Um código único será enviado para este email.",
|
||||
"otpEmailSend": "Enviar Código Único",
|
||||
"otpEmail": "Palavra-passe Única (OTP)",
|
||||
"otpEmailSubmit": "Submeter OTP",
|
||||
"backToEmail": "Voltar ao Email",
|
||||
"noSupportKey": "O servidor está a funcionar sem uma chave de suporte.<br/>Considere apoiar o projeto!",
|
||||
"accessDenied": "Acesso Negado",
|
||||
"accessDeniedDescription": "Não tem permissão para aceder a este recurso. Se isto for um erro, contacte o administrador.",
|
||||
"accessTokenError": "Erro ao verificar o token de acesso",
|
||||
"accessGranted": "Acesso Concedido",
|
||||
"accessUrlInvalid": "URL de Acesso Inválido",
|
||||
"accessGrantedDescription": "Foi-lhe concedido acesso a este recurso. A redirecionar...",
|
||||
"accessUrlInvalidDescription": "Este URL de acesso partilhado é inválido. Por favor, contacte o proprietário do recurso para obter um novo URL.",
|
||||
"tokenInvalid": "Token inválido",
|
||||
"pincodeInvalid": "Código inválido",
|
||||
"passwordErrorRequestReset": "Falha ao solicitar redefinição:",
|
||||
"passwordErrorReset": "Falha ao redefinir palavra-passe:",
|
||||
"passwordResetSuccess": "Palavra-passe redefinida com sucesso! Voltar ao início de sessão...",
|
||||
"passwordReset": "Redefinir Palavra-passe",
|
||||
"passwordResetDescription": "Siga os passos para redefinir a sua palavra-passe",
|
||||
"passwordResetSent": "Enviaremos um código de redefinição de palavra-passe para este email.",
|
||||
"passwordResetCode": "Código de Redefinição",
|
||||
"passwordResetCodeDescription": "Verifique o seu email para obter o código de redefinição.",
|
||||
"passwordNew": "Nova Palavra-passe",
|
||||
"passwordNewConfirm": "Confirmar Nova Palavra-passe",
|
||||
"pincodeAuth": "Código do Autenticador",
|
||||
"pincodeSubmit2": "Submeter Código",
|
||||
"passwordResetSubmit": "Solicitar Redefinição",
|
||||
"passwordBack": "Voltar à Palavra-passe",
|
||||
"loginBack": "Voltar ao início de sessão",
|
||||
"signup": "Registar",
|
||||
"loginStart": "Inicie sessão para começar",
|
||||
"idpOidcTokenValidating": "A validar token OIDC",
|
||||
"idpOidcTokenResponse": "Validar resposta do token OIDC",
|
||||
"idpErrorOidcTokenValidating": "Erro ao validar token OIDC",
|
||||
"idpConnectingTo": "A ligar a {name}",
|
||||
"idpConnectingToDescription": "A validar a sua identidade",
|
||||
"idpConnectingToProcess": "A conectar...",
|
||||
"idpConnectingToFinished": "Conectado",
|
||||
"idpErrorConnectingTo": "Ocorreu um problema ao ligar a {name}. Por favor, contacte o seu administrador.",
|
||||
"idpErrorNotFound": "IdP não encontrado"
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
"shareAccessHint": "Anyone with this link can access the resource. Share it with care.",
|
||||
"shareTokenUsage": "See Access Token Usage",
|
||||
"createLink": "Create Link",
|
||||
"resourceNotFound": "No resources found",
|
||||
"resourcesNotFound": "No resources found",
|
||||
"resourceSearch": "Search resources",
|
||||
"openMenu": "Open menu",
|
||||
"resource": "Resource",
|
||||
|
@ -802,5 +802,89 @@
|
|||
"redirectUrlAbout": "About Redirect URL",
|
||||
"redirectUrlAboutDescription": "This is the URL to which users will be redirected after authentication. You need to configure this URL in your identity provider settings.",
|
||||
"key": "Key",
|
||||
"createdAt": "Created At"
|
||||
"createdAt": "Created At",
|
||||
"expiresAt": "Expires At",
|
||||
"pangolinAuth": "Auth - Pangolin",
|
||||
"emailInvalid": "Invalid email address",
|
||||
"verificationCodeLengthRequirements": "Your verification code must be 8 characters.",
|
||||
"errorOccurred": "An error occurred",
|
||||
"emailErrorVerify": "Failed to verify email:",
|
||||
"emailVerified": "Email successfully verified! Redirecting you...",
|
||||
"verificationCodeErrorResend": "Failed to resend verification code:",
|
||||
"verificationCodeResend": "Verification code resent",
|
||||
"verificationCodeResendDescription": "We've resent a verification code to your email address. Please check your inbox.",
|
||||
"emailVerify": "Verify Email",
|
||||
"emailVerifyDescription": "Enter the verification code sent to your email address.",
|
||||
"verificationCode": "Verification Code",
|
||||
"verificationCodeEmailSent": "We sent a verification code to your email address.",
|
||||
"emailVerifySubmit": "Submit",
|
||||
"emailVerifyResendProgress": "Resending...",
|
||||
"emailVerifyResend": "Didn't receive a code? Click here to resend",
|
||||
"passwordNotMatch": "Passwords do not match",
|
||||
"signupError": "An error occurred while signing up",
|
||||
"pangolinLogoAlt": "Pangolin Logo",
|
||||
"inviteAlready": "Looks like you've been invited!",
|
||||
"inviteAlreadyDescription": "To accept the invite, you must log in or create an account.",
|
||||
"signupQuestion": "Already have an account?",
|
||||
"login": "Log in",
|
||||
"resourceNotFound": "Resource Not Found",
|
||||
"resourceNotFoundDescription": "The resource you're trying to access does not exist.",
|
||||
"pincodeRequirementsLength": "PIN must be exactly 6 digits",
|
||||
"pincodeRequirementsChars": "PIN must only contain numbers",
|
||||
"passwordRequirementsLength": "Password must be at least 1 character long",
|
||||
"otpEmailRequirementsLength": "OTP must be at least 1 character long",
|
||||
"otpEmailSent": "OTP Sent",
|
||||
"otpEmailSentDescription": "An OTP has been sent to your email",
|
||||
"otpEmailErrorAuthenticate": "Failed to authenticate with email",
|
||||
"pincodeErrorAuthenticate": "Failed to authenticate with pincode",
|
||||
"passwordErrorAuthenticate": "Failed to authenticate with password",
|
||||
"poweredBy": "Powered by",
|
||||
"authenticationRequired": "Authentication Required",
|
||||
"authenticationMethodChoose": "Choose your preferred method to access {name}",
|
||||
"authenticationRequest": "You must authenticate to access {name}",
|
||||
"user": "User",
|
||||
"pincodeInput": "6-digit PIN Code",
|
||||
"pincodeSubmit": "Log in with PIN",
|
||||
"passwordSubmit": "Log In with Password",
|
||||
"otpEmailDescription": "A one-time code will be sent to this email.",
|
||||
"otpEmailSend": "Send One-time Code",
|
||||
"otpEmail": "One-Time Password (OTP)",
|
||||
"otpEmailSubmit": "Submit OTP",
|
||||
"backToEmail": "Back to Email",
|
||||
"noSupportKey": "Server is running without a supporter key.<br/>Consider supporting the project!",
|
||||
"accessDenied": "Access Denied",
|
||||
"accessDeniedDescription": "You're not allowed to access this resource. If this is a mistake, please contact the administrator.",
|
||||
"accessTokenError": "Error checking access token",
|
||||
"accessGranted": "Access Granted",
|
||||
"accessUrlInvalid": "Access URL Invalid",
|
||||
"accessGrantedDescription": "You have been granted access to this resource. Redirecting you...",
|
||||
"accessUrlInvalidDescription": "This shared access URL is invalid. Please contact the resource owner for a new URL.",
|
||||
"tokenInvalid": "Invalid token",
|
||||
"pincodeInvalid": "Invalid code",
|
||||
"passwordErrorRequestReset": "Failed to request reset:",
|
||||
"passwordErrorReset": "Failed to reset password:",
|
||||
"passwordResetSuccess": "Password reset successfully! Back to log in...",
|
||||
"passwordReset": "Reset Password",
|
||||
"passwordResetDescription": "Follow the steps to reset your password",
|
||||
"passwordResetSent": "We'll send a password reset code to this email address.",
|
||||
"passwordResetCode": "Reset Code",
|
||||
"passwordResetCodeDescription": "Check your email for the reset code.",
|
||||
"passwordNew": "New Password",
|
||||
"passwordNewConfirm": "Confirm New Password",
|
||||
"pincodeAuth": "Authenticator Code",
|
||||
"pincodeSubmit2": "Submit Code",
|
||||
"passwordResetSubmit": "Request Reset",
|
||||
"passwordBack": "Back to Password",
|
||||
"loginBack": "Go back to log in",
|
||||
"signup": "Sign up",
|
||||
"loginStart": "Log in to get started",
|
||||
"idpOidcTokenValidating": "Validating OIDC token",
|
||||
"idpOidcTokenResponse": "Validate OIDC token response",
|
||||
"idpErrorOidcTokenValidating": "Error validating OIDC token",
|
||||
"idpConnectingTo": "Connecting to {name}",
|
||||
"idpConnectingToDescription": "Validating your identity",
|
||||
"idpConnectingToProcess": "Connecting...",
|
||||
"idpConnectingToFinished": "Connected",
|
||||
"idpErrorConnectingTo": "There was a problem connecting to {name}. Please contact your administrator.",
|
||||
"idpErrorNotFound": "IdP not found"
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ export default function CreateShareLinkForm({
|
|||
<CommandInput placeholder={t('resourceSearch')} />
|
||||
<CommandList>
|
||||
<CommandEmpty>
|
||||
{t('resourceNotFound')}
|
||||
{t('resourcesNotFound')}
|
||||
</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{resources.map(
|
||||
|
|
|
@ -57,9 +57,11 @@ const createSiteFormSchema = z.object({
|
|||
.string()
|
||||
.min(2, {
|
||||
message: "Name must be at least 2 characters."
|
||||
message: "Name must be at least 2 characters."
|
||||
})
|
||||
.max(30, {
|
||||
message: "Name must not be longer than 30 characters."
|
||||
message: "Name must not be longer than 30 characters."
|
||||
}),
|
||||
method: z.enum(["wireguard", "newt", "local"])
|
||||
});
|
||||
|
@ -273,6 +275,8 @@ PersistentKeepalive = 5`
|
|||
|
||||
const newtConfigDockerRun = `docker run -it fosrl/newt --id ${siteDefaults?.newtId} --secret ${siteDefaults?.newtSecret} --endpoint ${env.app.dashboardUrl}`;
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
return loadingPage ? (
|
||||
<LoaderPlaceholder height="300px" />
|
||||
) : (
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||
import { Loader2, CheckCircle2, AlertCircle } from "lucide-react";
|
||||
import { useLicenseStatusContext } from "@app/hooks/useLicenseStatusContext";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
type ValidateOidcTokenParams = {
|
||||
orgId: string;
|
||||
|
@ -36,11 +37,13 @@ export default function ValidateOidcToken(props: ValidateOidcTokenParams) {
|
|||
|
||||
const { licenseStatus, isLicenseViolation } = useLicenseStatusContext();
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
useEffect(() => {
|
||||
async function validate() {
|
||||
setLoading(true);
|
||||
|
||||
console.log("Validating OIDC token", {
|
||||
console.log(t('idpOidcTokenValidating'), {
|
||||
code: props.code,
|
||||
expectedState: props.expectedState,
|
||||
stateCookie: props.stateCookie
|
||||
|
@ -59,7 +62,7 @@ export default function ValidateOidcToken(props: ValidateOidcTokenParams) {
|
|||
storedState: props.stateCookie
|
||||
});
|
||||
|
||||
console.log("Validate OIDC token response", res.data);
|
||||
console.log(t('idpOidcTokenResponse'), res.data);
|
||||
|
||||
const redirectUrl = res.data.data.redirectUrl;
|
||||
|
||||
|
@ -76,7 +79,7 @@ export default function ValidateOidcToken(props: ValidateOidcTokenParams) {
|
|||
router.push(res.data.data.redirectUrl);
|
||||
}
|
||||
} catch (e) {
|
||||
setError(formatAxiosError(e, "Error validating OIDC token"));
|
||||
setError(formatAxiosError(e, t('idpErrorOidcTokenValidating')));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
@ -89,20 +92,20 @@ export default function ValidateOidcToken(props: ValidateOidcTokenParams) {
|
|||
<div className="flex items-center justify-center min-h-screen">
|
||||
<Card className="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<CardTitle>Connecting to {props.idp.name}</CardTitle>
|
||||
<CardDescription>Validating your identity</CardDescription>
|
||||
<CardTitle>{t('idpConnectingTo', {name: props.idp.name})}</CardTitle>
|
||||
<CardDescription>{t('idpConnectingToDescription')}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-col items-center space-y-4">
|
||||
{loading && (
|
||||
<div className="flex items-center space-x-2">
|
||||
<Loader2 className="h-5 w-5 animate-spin" />
|
||||
<span>Connecting...</span>
|
||||
<span>{t('idpConnectingToProcess')}</span>
|
||||
</div>
|
||||
)}
|
||||
{!loading && !error && (
|
||||
<div className="flex items-center space-x-2 text-green-600">
|
||||
<CheckCircle2 className="h-5 w-5" />
|
||||
<span>Connected</span>
|
||||
<span>{t('idpConnectingToFinished')}</span>
|
||||
</div>
|
||||
)}
|
||||
{error && (
|
||||
|
@ -110,9 +113,7 @@ export default function ValidateOidcToken(props: ValidateOidcTokenParams) {
|
|||
<AlertCircle className="h-5 w-5" />
|
||||
<AlertDescription className="flex flex-col space-y-2">
|
||||
<span>
|
||||
There was a problem connecting to{" "}
|
||||
{props.idp.name}. Please contact your
|
||||
administrator.
|
||||
{t('idpErrorConnectingTo', {name: props.idp.name})}
|
||||
</span>
|
||||
<span className="text-xs">{error}</span>
|
||||
</AlertDescription>
|
||||
|
|
|
@ -3,6 +3,7 @@ import ValidateOidcToken from "./ValidateOidcToken";
|
|||
import { idp } from "@server/db/schemas";
|
||||
import db from "@server/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
export default async function Page(props: {
|
||||
params: Promise<{ orgId: string; idpId: string }>;
|
||||
|
@ -23,8 +24,10 @@ export default async function Page(props: {
|
|||
.from(idp)
|
||||
.where(eq(idp.idpId, parseInt(params.idpId!)));
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
if (!idpRes) {
|
||||
return <div>IdP not found</div>;
|
||||
return <div>{t('idpErrorNotFound')}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -8,6 +8,7 @@ import { AxiosResponse } from "axios";
|
|||
import { ExternalLink } from "lucide-react";
|
||||
import { Metadata } from "next";
|
||||
import { cache } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `Auth - Pangolin`,
|
||||
|
@ -21,6 +22,7 @@ type AuthLayoutProps = {
|
|||
export default async function AuthLayout({ children }: AuthLayoutProps) {
|
||||
const getUser = cache(verifySession);
|
||||
const user = await getUser();
|
||||
const t = useTranslations();
|
||||
|
||||
const licenseStatusRes = await cache(
|
||||
async () =>
|
||||
|
|
|
@ -14,6 +14,7 @@ import { useRouter } from "next/navigation";
|
|||
import { useEffect } from "react";
|
||||
import Image from "next/image";
|
||||
import { cleanRedirect } from "@app/lib/cleanRedirect";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
type DashboardLoginFormProps = {
|
||||
redirect?: string;
|
||||
|
@ -38,23 +39,25 @@ export default function DashboardLoginForm({
|
|||
// logout();
|
||||
// });
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<Card className="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<div className="flex flex-row items-center justify-center">
|
||||
<Image
|
||||
src={`/logo/pangolin_orange.svg`}
|
||||
alt="Pangolin Logo"
|
||||
alt={t('pangolinLogoAlt')}
|
||||
width="100"
|
||||
height="100"
|
||||
/>
|
||||
</div>
|
||||
<div className="text-center space-y-1">
|
||||
<h1 className="text-2xl font-bold mt-1">
|
||||
Welcome to Pangolin
|
||||
{t('welcome')}
|
||||
</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Log in to get started
|
||||
{t('loginStart')}
|
||||
</p>
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
|
|
@ -9,6 +9,7 @@ import { cleanRedirect } from "@app/lib/cleanRedirect";
|
|||
import db from "@server/db";
|
||||
import { idp } from "@server/db/schemas";
|
||||
import { LoginFormIDP } from "@app/components/LoginForm";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
|
@ -40,6 +41,8 @@ export default async function Page(props: {
|
|||
name: idp.name
|
||||
})) as LoginFormIDP[];
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<>
|
||||
{isInvite && (
|
||||
|
@ -47,11 +50,10 @@ export default async function Page(props: {
|
|||
<div className="flex flex-col items-center">
|
||||
<Mail className="w-12 h-12 mb-4 text-primary" />
|
||||
<h2 className="text-2xl font-bold mb-2 text-center">
|
||||
Looks like you've been invited!
|
||||
{t('inviteAlready')}
|
||||
</h2>
|
||||
<p className="text-center">
|
||||
To accept the invite, you must log in or create an
|
||||
account.
|
||||
{t('inviteAlreadyDescription')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -70,7 +72,7 @@ export default async function Page(props: {
|
|||
}
|
||||
className="underline"
|
||||
>
|
||||
Sign up
|
||||
{t('signup')}
|
||||
</Link>
|
||||
</p>
|
||||
)}
|
||||
|
|
|
@ -44,6 +44,7 @@ import { useEnvContext } from "@app/hooks/useEnvContext";
|
|||
import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp";
|
||||
import { passwordSchema } from "@server/auth/passwordSchema";
|
||||
import { cleanRedirect } from "@app/lib/cleanRedirect";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const requestSchema = z.object({
|
||||
email: z.string().email()
|
||||
|
@ -122,6 +123,8 @@ export default function ResetPasswordForm({
|
|||
}
|
||||
});
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
async function onRequest(data: z.infer<typeof requestSchema>) {
|
||||
const { email } = data;
|
||||
|
||||
|
@ -200,9 +203,9 @@ export default function ResetPasswordForm({
|
|||
<div>
|
||||
<Card className="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<CardTitle>Reset Password</CardTitle>
|
||||
<CardTitle>{t('passwordReset')}</CardTitle>
|
||||
<CardDescription>
|
||||
Follow the steps to reset your password
|
||||
{t('passwordResetDescription')}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
|
@ -221,14 +224,13 @@ export default function ResetPasswordForm({
|
|||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Email</FormLabel>
|
||||
<FormLabel>{t('email')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
<FormDescription>
|
||||
We'll send a password reset
|
||||
code to this email address.
|
||||
{t('passwordResetSent')}
|
||||
</FormDescription>
|
||||
</FormItem>
|
||||
)}
|
||||
|
@ -249,7 +251,7 @@ export default function ResetPasswordForm({
|
|||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Email</FormLabel>
|
||||
<FormLabel>{t('email')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
|
@ -268,7 +270,7 @@ export default function ResetPasswordForm({
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Reset Code
|
||||
{t('passwordResetCode')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
|
@ -278,8 +280,7 @@ export default function ResetPasswordForm({
|
|||
</FormControl>
|
||||
<FormMessage />
|
||||
<FormDescription>
|
||||
Check your email for the
|
||||
reset code.
|
||||
{t('passwordResetCodeDescription')}
|
||||
</FormDescription>
|
||||
</FormItem>
|
||||
)}
|
||||
|
@ -292,7 +293,7 @@ export default function ResetPasswordForm({
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
New Password
|
||||
{t('passwordNew')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
|
@ -310,7 +311,7 @@ export default function ResetPasswordForm({
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Confirm New Password
|
||||
{t('passwordNewConfirm')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
|
@ -339,7 +340,7 @@ export default function ResetPasswordForm({
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Authenticator Code
|
||||
{t('pincodeAuth')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<div className="flex justify-center">
|
||||
|
@ -407,8 +408,8 @@ export default function ResetPasswordForm({
|
|||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
)}
|
||||
{state === "reset"
|
||||
? "Reset Password"
|
||||
: "Submit Code"}
|
||||
? t('passwordReset')
|
||||
: t('pincodeSubmit2')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
|
@ -422,7 +423,7 @@ export default function ResetPasswordForm({
|
|||
{isSubmitting && (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
)}
|
||||
Request Reset
|
||||
{t('passwordResetSubmit')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
|
@ -436,7 +437,7 @@ export default function ResetPasswordForm({
|
|||
mfaForm.reset();
|
||||
}}
|
||||
>
|
||||
Back to Password
|
||||
{t('passwordBack')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
|
@ -450,7 +451,7 @@ export default function ResetPasswordForm({
|
|||
form.reset();
|
||||
}}
|
||||
>
|
||||
Back to Email
|
||||
{t('backToEmail')}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { cache } from "react";
|
|||
import ResetPasswordForm from "./ResetPasswordForm";
|
||||
import Link from "next/link";
|
||||
import { cleanRedirect } from "@app/lib/cleanRedirect";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
|
@ -27,6 +28,8 @@ export default async function Page(props: {
|
|||
redirectUrl = cleanRedirect(searchParams.redirect);
|
||||
}
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<>
|
||||
<ResetPasswordForm
|
||||
|
@ -44,7 +47,7 @@ export default async function Page(props: {
|
|||
}
|
||||
className="underline"
|
||||
>
|
||||
Go back to log in
|
||||
{t('loginBack')}
|
||||
</Link>
|
||||
</p>
|
||||
</>
|
||||
|
|
|
@ -13,6 +13,7 @@ import { AuthWithAccessTokenResponse } from "@server/routers/resource";
|
|||
import { AxiosResponse } from "axios";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
type AccessTokenProps = {
|
||||
token: string;
|
||||
|
@ -29,6 +30,8 @@ export default function AccessToken({
|
|||
const { env } = useEnvContext();
|
||||
const api = createApiClient({ env });
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
function appendRequestToken(url: string, token: string) {
|
||||
const fullUrl = new URL(url);
|
||||
fullUrl.searchParams.append(
|
||||
|
@ -76,7 +79,7 @@ export default function AccessToken({
|
|||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error checking access token", e);
|
||||
console.error(t('accessTokenError'), e);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
@ -115,9 +118,9 @@ export default function AccessToken({
|
|||
|
||||
function renderTitle() {
|
||||
if (isValid) {
|
||||
return "Access Granted";
|
||||
return t('accessGranted');
|
||||
} else {
|
||||
return "Access URL Invalid";
|
||||
return t('accessUrlInvalid');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,18 +128,16 @@ export default function AccessToken({
|
|||
if (isValid) {
|
||||
return (
|
||||
<div>
|
||||
You have been granted access to this resource. Redirecting
|
||||
you...
|
||||
{t('accessGrantedDescription')}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div>
|
||||
This shared access URL is invalid. Please contact the
|
||||
resource owner for a new URL.
|
||||
{t('accessUrlInvalidDescription')}
|
||||
<div className="text-center mt-4">
|
||||
<Button>
|
||||
<Link href="/">Go Home</Link>
|
||||
<Link href="/">{t('goHome')}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,21 +9,23 @@ import {
|
|||
CardTitle,
|
||||
} from "@app/components/ui/card";
|
||||
import Link from "next/link";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
export default function ResourceAccessDenied() {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<Card className="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-center text-2xl font-bold">
|
||||
Access Denied
|
||||
{t('accessDenied')}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
You're not allowed to access this resource. If this is a mistake,
|
||||
please contact the administrator.
|
||||
{t('accessDeniedDescription')}
|
||||
<div className="text-center mt-4">
|
||||
<Button>
|
||||
<Link href="/">Go Home</Link>
|
||||
<Link href="/">{t('goHome')}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
|
|
@ -44,6 +44,7 @@ import { useEnvContext } from "@app/hooks/useEnvContext";
|
|||
import { toast } from "@app/hooks/useToast";
|
||||
import Link from "next/link";
|
||||
import { useSupporterStatusContext } from "@app/hooks/useSupporterStatusContext";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const pinSchema = z.object({
|
||||
pin: z
|
||||
|
@ -170,6 +171,8 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
return fullUrl.toString();
|
||||
}
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
const onWhitelistSubmit = (values: any) => {
|
||||
setLoadingLogin(true);
|
||||
api.post<AxiosResponse<AuthWithWhitelistResponse>>(
|
||||
|
@ -183,8 +186,8 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
setOtpState("otp_sent");
|
||||
submitOtpForm.setValue("email", values.email);
|
||||
toast({
|
||||
title: "OTP Sent",
|
||||
description: "An OTP has been sent to your email"
|
||||
title: t('otpEmailSent'),
|
||||
description: t('otpEmailSentDescription')
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -200,7 +203,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
.catch((e) => {
|
||||
console.error(e);
|
||||
setWhitelistError(
|
||||
formatAxiosError(e, "Failed to authenticate with email")
|
||||
formatAxiosError(e, t('otpEmailErrorAuthenticate'))
|
||||
);
|
||||
})
|
||||
.then(() => setLoadingLogin(false));
|
||||
|
@ -225,7 +228,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
.catch((e) => {
|
||||
console.error(e);
|
||||
setPincodeError(
|
||||
formatAxiosError(e, "Failed to authenticate with pincode")
|
||||
formatAxiosError(e, t('pincodeErrorAuthenticate'))
|
||||
);
|
||||
})
|
||||
.then(() => setLoadingLogin(false));
|
||||
|
@ -253,7 +256,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
.catch((e) => {
|
||||
console.error(e);
|
||||
setPasswordError(
|
||||
formatAxiosError(e, "Failed to authenticate with password")
|
||||
formatAxiosError(e, t('passwordErrorAuthenticate'))
|
||||
);
|
||||
})
|
||||
.finally(() => setLoadingLogin(false));
|
||||
|
@ -280,7 +283,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
<div>
|
||||
<div className="text-center mb-2">
|
||||
<span className="text-sm text-muted-foreground">
|
||||
Powered by{" "}
|
||||
{t('poweredBy')}{" "}
|
||||
<Link
|
||||
href="https://github.com/fosrl/pangolin"
|
||||
target="_blank"
|
||||
|
@ -293,11 +296,11 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
</div>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Authentication Required</CardTitle>
|
||||
<CardTitle>{t('authenticationRequired')}</CardTitle>
|
||||
<CardDescription>
|
||||
{numMethods > 1
|
||||
? `Choose your preferred method to access ${props.resource.name}`
|
||||
: `You must authenticate to access ${props.resource.name}`}
|
||||
? t('authenticationMethodChoose', {name: props.resource.name})
|
||||
: t('authenticationRequest', {name: props.resource.name})}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
|
@ -327,19 +330,19 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
{props.methods.password && (
|
||||
<TabsTrigger value="password">
|
||||
<Key className="w-4 h-4 mr-1" />{" "}
|
||||
Password
|
||||
{t('password')}
|
||||
</TabsTrigger>
|
||||
)}
|
||||
{props.methods.sso && (
|
||||
<TabsTrigger value="sso">
|
||||
<User className="w-4 h-4 mr-1" />{" "}
|
||||
User
|
||||
{t('user')}
|
||||
</TabsTrigger>
|
||||
)}
|
||||
{props.methods.whitelist && (
|
||||
<TabsTrigger value="whitelist">
|
||||
<AtSign className="w-4 h-4 mr-1" />{" "}
|
||||
Email
|
||||
{t('email')}
|
||||
</TabsTrigger>
|
||||
)}
|
||||
</TabsList>
|
||||
|
@ -362,7 +365,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
6-digit PIN Code
|
||||
{t('pincodeInput')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<div className="flex justify-center">
|
||||
|
@ -431,7 +434,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
disabled={loadingLogin}
|
||||
>
|
||||
<LockIcon className="w-4 h-4 mr-2" />
|
||||
Log in with PIN
|
||||
{t('pincodeSubmit')}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
|
@ -457,7 +460,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Password
|
||||
{t('password')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
|
@ -485,7 +488,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
disabled={loadingLogin}
|
||||
>
|
||||
<LockIcon className="w-4 h-4 mr-2" />
|
||||
Log In with Password
|
||||
{t('passwordSubmit')}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
|
@ -526,7 +529,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Email
|
||||
{t('email')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
|
@ -535,10 +538,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
/>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
A one-time
|
||||
code will be
|
||||
sent to this
|
||||
email.
|
||||
{t('otpEmailDescription')}
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
@ -560,7 +560,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
disabled={loadingLogin}
|
||||
>
|
||||
<Send className="w-4 h-4 mr-2" />
|
||||
Send One-time Code
|
||||
{t('otpEmailSend')}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
|
@ -582,9 +582,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
One-Time
|
||||
Password
|
||||
(OTP)
|
||||
{t('otpEmail')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
|
@ -612,7 +610,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
disabled={loadingLogin}
|
||||
>
|
||||
<LockIcon className="w-4 h-4 mr-2" />
|
||||
Submit OTP
|
||||
{t('otpEmailSubmit')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
|
@ -624,7 +622,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
submitOtpForm.reset();
|
||||
}}
|
||||
>
|
||||
Back to Email
|
||||
{t('backToEmail')}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
|
@ -637,9 +635,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
|
|||
{supporterStatus?.visible && (
|
||||
<div className="text-center mt-2">
|
||||
<span className="text-sm text-muted-foreground opacity-50">
|
||||
Server is running without a supporter key.
|
||||
<br />
|
||||
Consider supporting the project!
|
||||
{t('noSupportKey')}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -7,20 +7,23 @@ import {
|
|||
CardTitle,
|
||||
} from "@app/components/ui/card";
|
||||
import Link from "next/link";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
export default async function ResourceNotFound() {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<Card className="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-center text-2xl font-bold">
|
||||
Resource Not Found
|
||||
{t('resourceNotFound')}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
The resource you're trying to access does not exist.
|
||||
{t('resourceNotFoundDescription')}
|
||||
<div className="text-center mt-4">
|
||||
<Button>
|
||||
<Link href="/">Go Home</Link>
|
||||
<Link href="/">{t('goHome')}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
|
|
@ -71,6 +71,8 @@ export default function SignupForm({
|
|||
}
|
||||
});
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
async function onSubmit(values: z.infer<typeof formSchema>) {
|
||||
const { email, password } = values;
|
||||
|
||||
|
@ -113,15 +115,13 @@ export default function SignupForm({
|
|||
setLoading(false);
|
||||
}
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<Card className="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<div className="flex flex-row items-center justify-center">
|
||||
<Image
|
||||
src={`/logo/pangolin_orange.svg`}
|
||||
alt="Pangolin Logo"
|
||||
alt={t('pangolinLogoAlt')}
|
||||
width="100"
|
||||
height="100"
|
||||
/>
|
||||
|
|
|
@ -6,6 +6,7 @@ import { Mail } from "lucide-react";
|
|||
import Link from "next/link";
|
||||
import { redirect } from "next/navigation";
|
||||
import { cache } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
|
@ -20,6 +21,8 @@ export default async function Page(props: {
|
|||
|
||||
const isInvite = searchParams?.redirect?.includes("/invite");
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
if (env.flags.disableSignupWithoutInvite && !isInvite) {
|
||||
redirect("/");
|
||||
}
|
||||
|
@ -54,11 +57,10 @@ export default async function Page(props: {
|
|||
<div className="flex flex-col items-center">
|
||||
<Mail className="w-12 h-12 mb-4 text-primary" />
|
||||
<h2 className="text-2xl font-bold mb-2 text-center">
|
||||
Looks like you've been invited!
|
||||
{t('inviteAlready')}
|
||||
</h2>
|
||||
<p className="text-center">
|
||||
To accept the invite, you must log in or create an
|
||||
account.
|
||||
{t('inviteAlreadyDescription')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -71,7 +73,7 @@ export default async function Page(props: {
|
|||
/>
|
||||
|
||||
<p className="text-center text-muted-foreground mt-4">
|
||||
Already have an account?{" "}
|
||||
{t('signupQuestion')}{" "}
|
||||
<Link
|
||||
href={
|
||||
!redirectUrl
|
||||
|
@ -80,7 +82,7 @@ export default async function Page(props: {
|
|||
}
|
||||
className="underline"
|
||||
>
|
||||
Log in
|
||||
{t('login')}
|
||||
</Link>
|
||||
</p>
|
||||
</>
|
||||
|
|
|
@ -37,6 +37,7 @@ import { formatAxiosError } from "@app/lib/api";;
|
|||
import { createApiClient } from "@app/lib/api";
|
||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||
import { cleanRedirect } from "@app/lib/cleanRedirect";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const FormSchema = z.object({
|
||||
email: z.string().email({ message: "Invalid email address" }),
|
||||
|
@ -71,6 +72,8 @@ export default function VerifyEmailForm({
|
|||
},
|
||||
});
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
async function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
setIsSubmitting(true);
|
||||
|
||||
|
@ -114,8 +117,7 @@ export default function VerifyEmailForm({
|
|||
toast({
|
||||
variant: "default",
|
||||
title: "Verification code resent",
|
||||
description:
|
||||
"We've resent a verification code to your email address. Please check your inbox.",
|
||||
description: "We've resent a verification code to your email address. Please check your inbox.",
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -126,9 +128,9 @@ export default function VerifyEmailForm({
|
|||
<div>
|
||||
<Card className="w-full max-w-md">
|
||||
<CardHeader>
|
||||
<CardTitle>Verify Email</CardTitle>
|
||||
<CardTitle>{t('emailVerify')}</CardTitle>
|
||||
<CardDescription>
|
||||
Enter the verification code sent to your email address.
|
||||
{t('emailVerifyDescription')}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
|
@ -142,7 +144,7 @@ export default function VerifyEmailForm({
|
|||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Email</FormLabel>
|
||||
<FormLabel>{t('email')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
|
@ -159,7 +161,7 @@ export default function VerifyEmailForm({
|
|||
name="pin"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Verification Code</FormLabel>
|
||||
<FormLabel>{t('verificationCode')}</FormLabel>
|
||||
<FormControl>
|
||||
<div className="flex justify-center">
|
||||
<InputOTP
|
||||
|
@ -197,8 +199,7 @@ export default function VerifyEmailForm({
|
|||
</FormControl>
|
||||
<FormMessage />
|
||||
<FormDescription>
|
||||
We sent a verification code to your
|
||||
email address.
|
||||
{t('verificationCodeEmailSent')}
|
||||
</FormDescription>
|
||||
</FormItem>
|
||||
)}
|
||||
|
@ -226,7 +227,7 @@ export default function VerifyEmailForm({
|
|||
{isSubmitting && (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
)}
|
||||
Submit
|
||||
{t('emailVerifySubmit')}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
|
@ -241,8 +242,8 @@ export default function VerifyEmailForm({
|
|||
disabled={isResending}
|
||||
>
|
||||
{isResending
|
||||
? "Resending..."
|
||||
: "Didn't receive a code? Click here to resend"}
|
||||
? t('emailVerifyResendProgress')
|
||||
: t('emailVerifyResend')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue