fix(native): an error page in place of the server's keeps a way back to the address screen

A proxy's block page or a refused client certificate (Cloudflare's "Sorry, you have been blocked") left the app on a page without TREK's UI and no way to change the server. Any 4xx main-frame page that the client-certificate path does not handle now shows the sign-in bar with its own hint and "Change server", on iOS and Android. TestFlight feedback, 5.1.2.
This commit is contained in:
Maurice
2026-11-11 20:41:24 +00:00
parent 66b8f2c906
commit e0022c12c4
35 changed files with 155 additions and 15 deletions
@@ -47,7 +47,13 @@ public class MainActivity extends BridgeActivity {
// Set before any WebView callback can run: they are posted to this thread.
if (onServer) {
bridge.setWebViewClient(
new TrekWebViewClient(bridge, this::showAddressScreen, this::showSignInBar, TrekServerStore.getSignInHosts(this))
new TrekWebViewClient(
bridge,
this::showAddressScreen,
this::showSignInBar,
this::showErrorPageBar,
TrekServerStore.getSignInHosts(this)
)
);
}
TrekSharedFiles.receive(this, getIntent());
@@ -84,7 +90,10 @@ public class MainActivity extends BridgeActivity {
private View signInBar;
/** Whether the page is a proxy's sign-in page, and whether the keyboard is up over it. */
private boolean onSignInPage;
/** Whether the page is an error page in place of the server's (TrekWebViewClient.onReceivedHttpError). */
private boolean onErrorPage;
private boolean keyboardUp;
private TextView signInHint;
/**
* Over a proxy's sign-in page (Pangolin, authentik, ...): the server's UI is
@@ -100,9 +109,22 @@ public class MainActivity extends BridgeActivity {
});
}
/** The same bar over an error page in place of the server's, with words for that. */
private void showErrorPageBar(boolean show) {
runOnUiThread(() -> {
onErrorPage = show;
if (show && signInBar == null) signInBar = buildSignInBar();
updateSignInBar();
});
}
/** Out of the way while the keyboard is up: the form needs the room, and the bar is there again once it closes. */
private void updateSignInBar() {
if (signInBar != null) signInBar.setVisibility(onSignInPage && !keyboardUp ? View.VISIBLE : View.GONE);
if (signInBar == null) return;
if (signInHint != null) {
signInHint.setText(onSignInPage ? TrekServerStore.signInHintLabel(this) : TrekServerStore.errorPageHintLabel(this));
}
signInBar.setVisibility((onSignInPage || onErrorPage) && !keyboardUp ? View.VISIBLE : View.GONE);
}
private View buildSignInBar() {
@@ -118,6 +140,7 @@ public class MainActivity extends BridgeActivity {
bar.setElevation(6 * dp);
TextView hint = new TextView(this);
signInHint = hint;
hint.setText(TrekServerStore.signInHintLabel(this));
hint.setTextColor(0xFFE5E7EB);
hint.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12.5f);
@@ -26,6 +26,7 @@ final class TrekServerStore {
private static final String KEY_SERVER_CHECK = "server_check";
private static final String KEY_LABEL_SIGN_IN_HINT = "label_sign_in_hint";
private static final String KEY_LABEL_CHANGE_SERVER = "label_change_server";
private static final String KEY_LABEL_ERROR_PAGE_HINT = "label_error_page_hint";
/**
* The server API this build needs (MIN_NATIVE_API in serverAddress.ts). A
@@ -83,13 +84,21 @@ final class TrekServerStore {
* as the address screen passed them (setServer's `labels`): the server's UI
* is not there to say them. Null keeps the English fallback.
*/
static void setLabels(Context context, String signInHint, String changeServer) {
static void setLabels(Context context, String signInHint, String changeServer, String errorPageHint) {
SharedPreferences.Editor editor = prefs(context).edit();
if (signInHint != null) editor.putString(KEY_LABEL_SIGN_IN_HINT, signInHint);
if (changeServer != null) editor.putString(KEY_LABEL_CHANGE_SERVER, changeServer);
if (errorPageHint != null) editor.putString(KEY_LABEL_ERROR_PAGE_HINT, errorPageHint);
editor.commit();
}
static String errorPageHintLabel(Context context) {
return prefs(context).getString(
KEY_LABEL_ERROR_PAGE_HINT,
"This page is not from TREK: the server or a proxy in front of it refused the app. Check your proxy or certificate, or change the server."
);
}
static String signInHintLabel(Context context) {
return prefs(context).getString(
KEY_LABEL_SIGN_IN_HINT,
@@ -328,7 +328,12 @@ public class TrekShellPlugin extends Plugin {
TrekServerStore.setServer(getContext(), url, signInHostsOf(call));
JSObject labels = call.getObject("labels");
if (labels != null) {
TrekServerStore.setLabels(getContext(), labels.getString("signInHint"), labels.getString("changeServer"));
TrekServerStore.setLabels(
getContext(),
labels.getString("signInHint"),
labels.getString("changeServer"),
labels.getString("errorPageHint")
);
}
// A TREK Cloud purchase: the code that signs the buyer in, opened once after the first page.
String welcome = call.getString("welcome");
@@ -27,14 +27,25 @@ class TrekWebViewClient extends BridgeWebViewClient {
private final Runnable onUnreachable;
/** Told whether the page now shown is a proxy's sign-in page, for the bar with the way out. */
private final Consumer<Boolean> onSignInPage;
/** Told whether the page now shown is an error page in place of the server's, for the same bar. */
private final Consumer<Boolean> onErrorPage;
/** The main-frame address that last came back as a 4xx page nobody else handled. */
private String errorPageUrl;
private final Set<String> signInHosts;
/** A page of the server has shown since launch; from then on no sign-in host is learned (SignInRedirect). */
private boolean serverShown;
TrekWebViewClient(Bridge bridge, Runnable onUnreachable, Consumer<Boolean> onSignInPage, Set<String> signInHosts) {
TrekWebViewClient(
Bridge bridge,
Runnable onUnreachable,
Consumer<Boolean> onSignInPage,
Consumer<Boolean> onErrorPage,
Set<String> signInHosts
) {
super(bridge);
this.onUnreachable = onUnreachable;
this.onSignInPage = onSignInPage;
this.onErrorPage = onErrorPage;
this.signInHosts = new HashSet<>(signInHosts);
}
@@ -70,6 +81,11 @@ class TrekWebViewClient extends BridgeWebViewClient {
public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
super.doUpdateVisitedHistory(view, url, isReload);
onSignInPage.accept(url != null && isSignInHost(Uri.parse(url)));
// The 4xx answer arrives before this commit or after it; either way the
// flag is read once here, so the next page clears the bar again.
boolean error = url != null && url.equals(errorPageUrl);
errorPageUrl = null;
onErrorPage.accept(error);
}
/** After the server's first page, a pending welcome code opens the welcome page once (TrekServerStore.takeWelcomeUrl). */
@@ -132,10 +148,12 @@ class TrekWebViewClient extends BridgeWebViewClient {
/**
* Only a 5xx on the page itself means the server is down (a proxy's 502 or
* 503 while TREK restarts). A 4xx page is left alone: the server answered,
* and TREK serves its UI for every other path. The exception is a proxy
* that asked this page for a client certificate and got none, as Cloudflare
* does with a 403: the address screen then says so and offers to add one.
* 503 while TREK restarts). A 4xx page is not TREK's, which serves its UI for
* every path: a proxy that asked this page for a client certificate and got
* none, as Cloudflare does with a 403, sends the app to the address screen,
* which says so and offers to add one. Any other 4xx page (a proxy's block
* page, a certificate it refused) stays up with the bar and its way out, so
* the app is never stuck on a page without TREK's UI.
*/
@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
@@ -144,6 +162,9 @@ class TrekWebViewClient extends BridgeWebViewClient {
super.onReceivedHttpError(view, request, errorResponse);
} else if (status >= 500 || (status >= 400 && wantedCertificate(request.getUrl()))) {
onUnreachable.run();
} else if (status >= 400) {
errorPageUrl = request.getUrl().toString();
onErrorPage.accept(true);
}
}
@@ -68,6 +68,10 @@ class TrekBridgeViewController: CAPBridgeViewController {
private var urlObservation: NSKeyValueObservation?
private var insetObservation: NSKeyValueObservation?
private var onSignInPage = false
/// Whether the main frame shows an error page in place of the server's (a 4xx
/// nobody else handled: a proxy's block page, a client certificate it refused).
private var onErrorPage = false
private var signInHint: UILabel?
private var keyboardUp = false
/// How far the keyboard reaches into the view while it is up.
private var keyboardRoom: CGFloat = 0
@@ -97,9 +101,20 @@ class TrekBridgeViewController: CAPBridgeViewController {
updateSignInBar()
}
private func errorPageChanged(_ error: Bool) {
onErrorPage = error
if error && signInBar == nil { signInBar = makeSignInBar() }
updateSignInBar()
}
/// Out of the way while the keyboard is up: the form needs the room.
private func updateSignInBar() {
signInBar?.isHidden = !(onSignInPage && !keyboardUp)
let labels = TrekServerStore.labels
signInHint?.text = onSignInPage
? labels["signInHint"]
?? "Passkeys and security keys do not work on this page in the app. Sign in with a password, or let the app through your proxy."
: labels["errorPageHint"] ?? "This page is not from TREK: the server or a proxy in front of it refused the app. Check your proxy or certificate, or change the server."
signInBar?.isHidden = !((onSignInPage || onErrorPage) && !keyboardUp)
applyInset()
}
@@ -108,7 +123,7 @@ class TrekBridgeViewController: CAPBridgeViewController {
private func applyInset() {
guard let scrollView = webView?.scrollView else { return }
let wanted: CGFloat
if onSignInPage {
if onSignInPage || onErrorPage {
if keyboardUp {
wanted = keyboardRoom
} else if let bar = signInBar {
@@ -172,6 +187,7 @@ class TrekBridgeViewController: CAPBridgeViewController {
hint.font = .preferredFont(forTextStyle: .footnote)
hint.adjustsFontForContentSizeCategory = true
hint.numberOfLines = 0
signInHint = hint
hint.translatesAutoresizingMaskIntoConstraints = false
let change = UIButton(type: .system)
@@ -748,7 +764,9 @@ final class TrekNavigationProxy: NSObject, WKNavigationDelegate {
/// A proxy that asked the page for a client certificate, got none and
/// answered with its own refusal (Cloudflare's 403, nginx's 400) sends the
/// app to the address screen, which says so and offers to add one, rather
/// than leaving the proxy's error page up.
/// than leaving the proxy's error page up. Any other 4xx page is not TREK's,
/// which serves its UI for every path (a proxy's block page, a certificate it
/// refused): it stays up with the bar and its way out to another server.
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse,
decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
if navigationResponse.isForMainFrame, let http = navigationResponse.response as? HTTPURLResponse,
@@ -758,6 +776,10 @@ final class TrekNavigationProxy: NSObject, WKNavigationDelegate {
inner.webView?(webView, didFailProvisionalNavigation: nil, withError: URLError(.clientCertificateRequired))
return
}
if navigationResponse.isForMainFrame, let http = navigationResponse.response as? HTTPURLResponse {
let error = http.statusCode >= 400 && http.statusCode < 500
DispatchQueue.main.async { [weak self] in self?.errorPageChanged(error) }
}
let selector = NSSelectorFromString("webView:decidePolicyForNavigationResponse:decisionHandler:")
guard (inner as AnyObject).responds(to: selector) else {
decisionHandler(.allow)
+5 -1
View File
@@ -1281,7 +1281,11 @@ async function connected(url: string, signInHosts: string[] = [], welcome?: stri
await new Promise((r) => setTimeout(r, 700));
await TrekShell.setServer({
url,
labels: { signInHint: t('native.signInBar.hint'), changeServer: t('native.changeServer') },
labels: {
signInHint: t('native.signInBar.hint'),
changeServer: t('native.changeServer'),
errorPageHint: t('native.errorPageBar.hint'),
},
...(signInHosts.length ? { signInHosts } : {}),
...(welcome ? { welcome } : {}),
});
+3 -2
View File
@@ -27,13 +27,14 @@ export interface TrekShellPlugin {
* opens the server's welcome page with it, which signs the buyer in. A build
* without this option ignores it and opens the server as usual.
* `labels` are the words of the bar the app shows over a proxy's sign-in page,
* in the user's language: the server's UI is not there to say them.
* or over an error page in place of the server's (a proxy's block page), in the
* user's language: the server's UI is not there to say them.
*/
setServer(options: {
url: string;
signInHosts?: string[];
welcome?: string;
labels?: { signInHint: string; changeServer: string };
labels?: { signInHint: string; changeServer: string; errorPageHint?: string };
}): Promise<void>;
/** Forgets the server and returns to the address screen. */
resetServer(): Promise<void>;
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'تعذّر على TREK الوصول إلى {server}. تحقق من اتصالك ثم حاول مرة أخرى.',
'native.offline.retry': 'إعادة المحاولة',
'native.changeServer': 'تغيير الخادم',
'native.errorPageBar.hint':
'هذه الصفحة ليست من TREK: رفض الخادم أو وكيل أمامه التطبيق. تحقق من الوكيل أو الشهادة، أو غيّر الخادم.',
'native.signInBar.hint':
'لا تعمل مفاتيح المرور ومفاتيح الأمان على هذه الصفحة داخل التطبيق. سجّل الدخول بكلمة مرور، أو اسمح للتطبيق بتجاوز الوكيل.',
'native.login.failed': 'تعذّر تسجيل الدخول. يرجى المحاولة مرة أخرى.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK {server} ünvanına çata bilmədi. Bağlantınızı yoxlayın və yenidən cəhd edin.',
'native.offline.retry': 'Yenidən cəhd et',
'native.changeServer': 'Serveri dəyiş',
'native.errorPageBar.hint':
'Bu səhifə TREK-ə aid deyil: server və ya onun qarşısındakı proxy tətbiqi rədd etdi. Proxy-ni və ya sertifikatı yoxlayın, ya da serveri dəyişin.',
'native.signInBar.hint':
'Passkey və təhlükəsizlik açarları tətbiqdə bu səhifədə işləmir. Parolla daxil olun və ya tətbiqi proksinizdən keçirin.',
'native.login.failed': 'Daxil olmaq alınmadı. Zəhmət olmasa, yenidən cəhd edin.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'O TREK não conseguiu acessar {server}. Verifique sua conexão e tente novamente.',
'native.offline.retry': 'Tentar novamente',
'native.changeServer': 'Trocar de servidor',
'native.errorPageBar.hint':
'Esta página não é do TREK: o servidor ou um proxy à frente dele recusou o app. Verifique seu proxy ou certificado, ou troque de servidor.',
'native.signInBar.hint':
'Passkeys e chaves de segurança não funcionam nesta página no app. Entre com uma senha ou libere o app no seu proxy.',
'native.login.failed': 'Não foi possível entrar. Tente novamente.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK no ha pogut connectar amb {server}. Comprova la connexió i torna-ho a provar.',
'native.offline.retry': 'Torna-ho a provar',
'native.changeServer': 'Canvia de servidor',
'native.errorPageBar.hint':
'Aquesta pàgina no és de TREK: el servidor o un proxy davant seu ha rebutjat l’app. Comprova el proxy o el certificat, o canvia de servidor.',
'native.signInBar.hint':
'Les claus d’accés i les claus de seguretat no funcionen en aquesta pàgina dins l’app. Inicia la sessió amb una contrasenya o deixa passar l’app pel teu proxy.',
'native.login.failed': 'No s’ha pogut iniciar la sessió. Torna-ho a provar.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK se nepodařilo spojit s {server}. Zkontrolujte připojení a zkuste to znovu.',
'native.offline.retry': 'Zkusit znovu',
'native.changeServer': 'Změnit server',
'native.errorPageBar.hint':
'Tato stránka není z TREK: server nebo proxy před ním aplikaci odmítl. Zkontroluj proxy nebo certifikát, nebo změň server.',
'native.signInBar.hint':
'Přístupové klíče a bezpečnostní klíče na této stránce v aplikaci nefungují. Přihlaste se heslem, nebo aplikaci propusťte přes svůj proxy.',
'native.login.failed': 'Přihlášení se nezdařilo. Zkuste to prosím znovu.',
+2
View File
@@ -20,6 +20,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK konnte {server} nicht erreichen. Prüfe deine Verbindung und versuche es erneut.',
'native.offline.retry': 'Erneut versuchen',
'native.changeServer': 'Server wechseln',
'native.errorPageBar.hint':
'Diese Seite stammt nicht von TREK: Der Server oder ein Proxy davor hat die App abgewiesen. Prüf deinen Proxy oder dein Zertifikat, oder wechsle den Server.',
'native.signInBar.hint':
'Passkeys und Sicherheitsschlüssel funktionieren auf dieser Seite in der App nicht. Melde dich mit Passwort an oder lass die App an deinem Proxy vorbei.',
'native.login.failed': 'Die Anmeldung hat nicht geklappt. Bitte versuche es erneut.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK could not reach {server}. Check your connection and try again.',
'native.offline.retry': 'Try again',
'native.changeServer': 'Change server',
'native.errorPageBar.hint':
'This page is not from TREK: the server or a proxy in front of it refused the app. Check your proxy or certificate, or change the server.',
'native.signInBar.hint':
'Passkeys and security keys do not work on this page in the app. Sign in with a password, or let the app through your proxy.',
'native.login.failed': 'Signing in did not work. Please try again.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK no pudo conectar con {server}. Revisa tu conexión e inténtalo de nuevo.',
'native.offline.retry': 'Reintentar',
'native.changeServer': 'Cambiar de servidor',
'native.errorPageBar.hint':
'Esta página no es de TREK: el servidor o un proxy delante de él ha rechazado la app. Revisa tu proxy o certificado, o cambia de servidor.',
'native.signInBar.hint':
'Las llaves de acceso y las llaves de seguridad no funcionan en esta página dentro de la app. Inicia sesión con una contraseña o deja pasar la app por tu proxy.',
'native.login.failed': 'No se pudo iniciar sesión. Inténtalo de nuevo.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK ei jõudnud serverini {server}. Kontrolli oma ühendust ja proovi uuesti.',
'native.offline.retry': 'Proovi uuesti',
'native.changeServer': 'Vaheta serverit',
'native.errorPageBar.hint':
'See leht ei ole TREKilt: server või selle ees olev proksi lükkas rakenduse tagasi. Kontrolli proksit või sertifikaati või vaheta serverit.',
'native.signInBar.hint':
'Pääsuvõtmed ja turvavõtmed ei tööta sellel lehel rakenduses. Logi sisse parooliga või lase rakendus oma puhverserverist läbi.',
'native.login.failed': 'Sisselogimine ei õnnestunud. Palun proovi uuesti.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK n’a pas pu joindre {server}. Vérifiez votre connexion et réessayez.',
'native.offline.retry': 'Réessayer',
'native.changeServer': 'Changer de serveur',
'native.errorPageBar.hint':
'Cette page ne vient pas de TREK : le serveur ou un proxy placé devant a refusé l’app. Vérifie ton proxy ou ton certificat, ou change de serveur.',
'native.signInBar.hint':
'Les clés d’accès et les clés de sécurité ne fonctionnent pas sur cette page dans l’application. Connectez-vous avec un mot de passe ou laissez passer l’application par votre proxy.',
'native.login.failed': 'La connexion n’a pas abouti. Veuillez réessayer.',
+2
View File
@@ -20,6 +20,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'Το TREK δεν μπόρεσε να συνδεθεί στο {server}. Ελέγξτε τη σύνδεσή σας και δοκιμάστε ξανά.',
'native.offline.retry': 'Δοκιμάστε ξανά',
'native.changeServer': 'Αλλαγή διακομιστή',
'native.errorPageBar.hint':
'Αυτή η σελίδα δεν είναι από το TREK: ο διακομιστής ή ένας proxy μπροστά του απέρριψε την εφαρμογή. Έλεγξε τον proxy ή το πιστοποιητικό σου ή άλλαξε διακομιστή.',
'native.signInBar.hint':
'Τα passkeys και τα κλειδιά ασφαλείας δεν λειτουργούν σε αυτή τη σελίδα μέσα στην εφαρμογή. Συνδεθείτε με κωδικό ή αφήστε την εφαρμογή να περνά από τον διακομιστή μεσολάβησης.',
'native.login.failed': 'Η σύνδεση δεν ολοκληρώθηκε. Δοκιμάστε ξανά.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK לא הצליח להגיע אל {server}. בדקו את החיבור ונסו שוב.',
'native.offline.retry': 'נסו שוב',
'native.changeServer': 'החלפת שרת',
'native.errorPageBar.hint':
'הדף הזה אינו של TREK: השרת או פרוקסי שלפניו דחה את האפליקציה. בדקו את הפרוקסי או את האישור, או החליפו שרת.',
'native.signInBar.hint':
'מפתחות גישה ומפתחות אבטחה לא עובדים בדף הזה באפליקציה. התחבר עם סיסמה, או אפשר לאפליקציה לעבור דרך ה־proxy שלך.',
'native.login.failed': 'ההתחברות נכשלה. אנא נסו שוב.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'A TREK nem érte el ezt: {server}. Ellenőrizd a kapcsolatot, és próbáld újra.',
'native.offline.retry': 'Újra',
'native.changeServer': 'Szerver módosítása',
'native.errorPageBar.hint':
'Ez az oldal nem a TREK-től származik: a szerver vagy az előtte álló proxy elutasította az alkalmazást. Ellenőrizd a proxyt vagy a tanúsítványt, vagy válts szervert.',
'native.signInBar.hint':
'A jelkulcsok és a biztonsági kulcsok ezen az oldalon nem működnek az alkalmazásban. Jelentkezz be jelszóval, vagy engedd át az alkalmazást a proxyn.',
'native.login.failed': 'A bejelentkezés nem sikerült. Próbáld újra.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK tidak dapat menjangkau {server}. Periksa koneksimu dan coba lagi.',
'native.offline.retry': 'Coba lagi',
'native.changeServer': 'Ganti server',
'native.errorPageBar.hint':
'Halaman ini bukan dari TREK: server atau proxy di depannya menolak aplikasi. Periksa proxy atau sertifikat Anda, atau ganti server.',
'native.signInBar.hint':
'Passkey dan kunci keamanan tidak berfungsi di halaman ini dalam aplikasi. Masuk dengan kata sandi, atau izinkan aplikasi melewati proxy Anda.',
'native.login.failed': 'Gagal masuk. Silakan coba lagi.',
+2
View File
@@ -20,6 +20,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK non è riuscito a raggiungere {server}. Controlla la connessione e riprova.',
'native.offline.retry': 'Riprova',
'native.changeServer': 'Cambia server',
'native.errorPageBar.hint':
'Questa pagina non è di TREK: il server o un proxy davanti a esso ha rifiutato l’app. Controlla il proxy o il certificato, oppure cambia server.',
'native.signInBar.hint':
'Le passkey e le chiavi di sicurezza non funzionano su questa pagina nell’app. Accedi con una password o lascia passare l’app dal tuo proxy.',
'native.login.failed': 'L’accesso non è riuscito. Riprova.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK は {server} に接続できませんでした。接続を確認して、もう一度お試しください。',
'native.offline.retry': '再試行',
'native.changeServer': 'サーバーを変更',
'native.errorPageBar.hint':
'このページは TREK のものではありません。サーバーまたはその前のプロキシがアプリを拒否しました。プロキシや証明書を確認するか、サーバーを変更してください。',
'native.signInBar.hint':
'このページではアプリ内でパスキーとセキュリティキーを使えません。パスワードでサインインするか、プロキシでアプリを通過させてください。',
'native.login.failed': 'ログインできませんでした。もう一度お試しください。',
+2
View File
@@ -18,6 +18,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK이 {server}에 연결하지 못했습니다. 연결 상태를 확인한 후 다시 시도하세요.',
'native.offline.retry': '다시 시도',
'native.changeServer': '서버 변경',
'native.errorPageBar.hint':
'이 페이지는 TREK이 아닙니다. 서버 또는 그 앞의 프록시가 앱을 거부했습니다. 프록시나 인증서를 확인하거나 서버를 변경하세요.',
'native.signInBar.hint':
'이 페이지에서는 앱 안에서 패스키와 보안 키를 사용할 수 없습니다. 비밀번호로 로그인하거나 프록시에서 앱을 통과시키세요.',
'native.login.failed': '로그인하지 못했습니다. 다시 시도하세요.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK kon {server} niet bereiken. Controleer je verbinding en probeer het opnieuw.',
'native.offline.retry': 'Opnieuw proberen',
'native.changeServer': 'Server wijzigen',
'native.errorPageBar.hint':
'Deze pagina komt niet van TREK: de server of een proxy ervoor heeft de app geweigerd. Controleer je proxy of certificaat, of wissel van server.',
'native.signInBar.hint':
'Passkeys en beveiligingssleutels werken op deze pagina niet in de app. Meld je aan met een wachtwoord of laat de app door je proxy.',
'native.login.failed': 'Inloggen is niet gelukt. Probeer het opnieuw.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK nie mógł połączyć się z {server}. Sprawdź połączenie i spróbuj ponownie.',
'native.offline.retry': 'Spróbuj ponownie',
'native.changeServer': 'Zmień serwer',
'native.errorPageBar.hint':
'Ta strona nie pochodzi z TREK: serwer lub proxy przed nim odrzucił aplikację. Sprawdź proxy lub certyfikat albo zmień serwer.',
'native.signInBar.hint':
'Klucze dostępu i klucze bezpieczeństwa nie działają na tej stronie w aplikacji. Zaloguj się hasłem albo przepuść aplikację przez swój serwer proxy.',
'native.login.failed': 'Logowanie się nie powiodło. Spróbuj ponownie.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK не удалось подключиться к {server}. Проверьте подключение и повторите попытку.',
'native.offline.retry': 'Повторить',
'native.changeServer': 'Сменить сервер',
'native.errorPageBar.hint':
'Эта страница не от TREK: сервер или прокси перед ним отклонил приложение. Проверьте прокси или сертификат либо смените сервер.',
'native.signInBar.hint':
'Ключи доступа и ключи безопасности не работают на этой странице в приложении. Войдите с паролем или пропустите приложение через свой прокси.',
'native.login.failed': 'Не удалось войти. Попробуйте ещё раз.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK sa nepodarilo spojiť so serverom {server}. Skontrolujte pripojenie a skúste to znova.',
'native.offline.retry': 'Skúsiť znova',
'native.changeServer': 'Zmeniť server',
'native.errorPageBar.hint':
'Táto stránka nie je z TREK: server alebo proxy pred ním aplikáciu odmietol. Skontroluj proxy alebo certifikát, alebo zmeň server.',
'native.signInBar.hint':
'Prístupové kľúče a bezpečnostné kľúče na tejto stránke v aplikácii nefungujú. Prihláste sa heslom alebo aplikáciu prepustite cez svoj proxy.',
'native.login.failed': 'Prihlásenie sa nepodarilo. Skúste to, prosím, znova.',
+2
View File
@@ -20,6 +20,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK kunde inte nå {server}. Kontrollera din anslutning och försök igen.',
'native.offline.retry': 'Försök igen',
'native.changeServer': 'Byt server',
'native.errorPageBar.hint':
'Den här sidan kommer inte från TREK: servern eller en proxy framför den nekade appen. Kontrollera din proxy eller ditt certifikat, eller byt server.',
'native.signInBar.hint':
'Nyckelpass och säkerhetsnycklar fungerar inte på den här sidan i appen. Logga in med lösenord eller släpp igenom appen i din proxy.',
'native.login.failed': 'Inloggningen misslyckades. Försök igen.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK เข้าถึง {server} ไม่ได้ โปรดตรวจสอบการเชื่อมต่อแล้วลองอีกครั้ง',
'native.offline.retry': 'ลองอีกครั้ง',
'native.changeServer': 'เปลี่ยนเซิร์ฟเวอร์',
'native.errorPageBar.hint':
'หน้านี้ไม่ได้มาจาก TREK: เซิร์ฟเวอร์หรือพร็อกซีที่อยู่ข้างหน้าปฏิเสธแอป ตรวจสอบพร็อกซีหรือใบรับรอง หรือเปลี่ยนเซิร์ฟเวอร์',
'native.signInBar.hint':
'พาสคีย์และคีย์ความปลอดภัยใช้ไม่ได้บนหน้านี้ในแอป ลงชื่อเข้าใช้ด้วยรหัสผ่าน หรืออนุญาตให้แอปผ่านพร็อกซีของคุณ',
'native.login.failed': 'เข้าสู่ระบบไม่สำเร็จ โปรดลองอีกครั้ง',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK, {server} adresine ulaşamadı. Bağlantını kontrol edip tekrar dene.',
'native.offline.retry': 'Tekrar dene',
'native.changeServer': 'Sunucuyu değiştir',
'native.errorPageBar.hint':
'Bu sayfa TREK’ten değil: sunucu veya önündeki proxy uygulamayı reddetti. Proxy’ni veya sertifikanı kontrol et ya da sunucuyu değiştir.',
'native.signInBar.hint':
'Geçiş anahtarları ve güvenlik anahtarları uygulamada bu sayfada çalışmaz. Parolayla giriş yapın veya uygulamayı proxy’nizden geçirin.',
'native.login.failed': 'Giriş yapılamadı. Lütfen tekrar dene.',
+2
View File
@@ -19,6 +19,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK не вдалося підключитися до {server}. Перевірте з’єднання та спробуйте ще раз.',
'native.offline.retry': 'Спробувати ще раз',
'native.changeServer': 'Змінити сервер',
'native.errorPageBar.hint':
'Ця сторінка не від TREK: сервер або проксі перед ним відхилив застосунок. Перевірте проксі чи сертифікат або змініть сервер.',
'native.signInBar.hint':
'Ключі доступу та ключі безпеки не працюють на цій сторінці в застосунку. Увійдіть із паролем або пропустіть застосунок через свій проксі.',
'native.login.failed': 'Не вдалося увійти. Спробуйте ще раз.',
+2
View File
@@ -20,6 +20,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK không thể kết nối tới {server}. Hãy kiểm tra kết nối và thử lại.',
'native.offline.retry': 'Thử lại',
'native.changeServer': 'Đổi máy chủ',
'native.errorPageBar.hint':
'Trang này không phải của TREK: máy chủ hoặc proxy phía trước đã từ chối ứng dụng. Hãy kiểm tra proxy hoặc chứng chỉ, hoặc đổi máy chủ.',
'native.signInBar.hint':
'Khóa truy cập và khóa bảo mật không hoạt động trên trang này trong ứng dụng. Hãy đăng nhập bằng mật khẩu hoặc cho ứng dụng đi qua proxy của bạn.',
'native.login.failed': 'Đăng nhập không thành công. Vui lòng thử lại.',
+2
View File
@@ -17,6 +17,8 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK 無法連線到 {server}。請檢查網路連線後再試一次。',
'native.offline.retry': '再試一次',
'native.changeServer': '更換伺服器',
'native.errorPageBar.hint':
'此頁面並非來自 TREK:伺服器或其前方的代理拒絕了應用程式。請檢查代理或憑證,或更換伺服器。',
'native.signInBar.hint': '在 App 中,此頁面無法使用通行密鑰和安全金鑰。請使用密碼登入,或讓 App 略過你的代理伺服器。',
'native.login.failed': '登入未成功,請再試一次。',
'native.handoff.title': '在 App 中繼續',
+1
View File
@@ -17,6 +17,7 @@ const native: TranslationStrings = {
'native.offline.hint': 'TREK 无法连接到 {server}。请检查网络连接后重试。',
'native.offline.retry': '重试',
'native.changeServer': '更换服务器',
'native.errorPageBar.hint': '此页面并非来自 TREK:服务器或其前面的代理拒绝了应用。请检查代理或证书,或更换服务器。',
'native.signInBar.hint': '在应用中,此页面无法使用通行密钥和安全密钥。请使用密码登录,或让应用绕过你的代理。',
'native.login.failed': '登录未成功,请重试。',
'native.handoff.title': '在应用中继续',