From 377c283d861fbbf57c3a6dea79dabf7cf5111e43 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Sun, 27 Sep 2026 04:53:49 +0200 Subject: [PATCH] fix: say up front when the mobile app cannot use an http mail server The app refuses a JMAP server over plain http (loopback aside), yet the desktop issued a code, reported "Signed in on your phone" once it was redeemed, and the phone failed. Linking now stops before the step-up with an explanation. --- app/api/auth/pair/create/route.ts | 8 ++++++++ .../__tests__/link-device-section.test.tsx | 1 + .../settings/account-security-settings.tsx | 3 +++ lib/__tests__/pair-create-route.test.ts | 16 ++++++++++++++++ lib/auth/pair-bundle.ts | 8 ++++++++ locales/ar/common.json | 3 ++- locales/ca/common.json | 3 ++- locales/cs/common.json | 3 ++- locales/da/common.json | 3 ++- locales/de/common.json | 3 ++- locales/en/common.json | 3 ++- locales/es/common.json | 3 ++- locales/fa/common.json | 3 ++- locales/fr/common.json | 3 ++- locales/he/common.json | 3 ++- locales/hu/common.json | 3 ++- locales/it/common.json | 3 ++- locales/ja/common.json | 3 ++- locales/ko/common.json | 3 ++- locales/lv/common.json | 3 ++- locales/mn/common.json | 3 ++- locales/nb/common.json | 3 ++- locales/nl/common.json | 3 ++- locales/pl/common.json | 3 ++- locales/pt/common.json | 3 ++- locales/ro/common.json | 3 ++- locales/ru/common.json | 3 ++- locales/sk/common.json | 3 ++- locales/tr/common.json | 3 ++- locales/uk/common.json | 3 ++- locales/zh-TW/common.json | 3 ++- locales/zh/common.json | 3 ++- 32 files changed, 90 insertions(+), 27 deletions(-) diff --git a/app/api/auth/pair/create/route.ts b/app/api/auth/pair/create/route.ts index 48e977a8e..f7d85eff4 100644 --- a/app/api/auth/pair/create/route.ts +++ b/app/api/auth/pair/create/route.ts @@ -4,6 +4,7 @@ import { logger } from '@/lib/logger'; import { createPairingCode, isGrantAvailable, stashGrant } from '@/lib/auth/pairing-store'; import { pairingOwner, readPairReauthFromStore, setPairReauthInStore } from '@/lib/auth/pair-reauth'; import { mintGrantWithPassword } from '@/lib/auth/pair-grant'; +import { appAcceptsServerUrl } from '@/lib/auth/pair-bundle'; import { beginPairStepUp, pairAttemptKey, settlePairStepUp } from '@/lib/auth/pair-attempts'; import { hasSessionSecret } from '@/lib/auth/session-secret'; import { readStalwartAuthContextFromStore } from '@/lib/stalwart/auth-context'; @@ -112,6 +113,13 @@ export async function POST(request: NextRequest) { } const owner = pairingOwner(slot, context.username); + // The app refuses a mail server over plain http. Say so here, before a + // password attempt is spent and before the desktop would report a phone + // that could never connect as signed in. + if (!appAcceptsServerUrl(context.serverUrl)) { + return NextResponse.json({ error: 'insecure_server' }, { status: 400 }); + } + let grantId: string; const password = typeof body?.password === 'string' ? body.password : ''; if (password) { diff --git a/components/settings/__tests__/link-device-section.test.tsx b/components/settings/__tests__/link-device-section.test.tsx index c093d335c..019b9df38 100644 --- a/components/settings/__tests__/link-device-section.test.tsx +++ b/components/settings/__tests__/link-device-section.test.tsx @@ -329,6 +329,7 @@ describe('LinkDeviceSection step-up', () => { [500, 'session_secret_required', 'link_device.error_session_secret'], [502, 'server_unreachable', 'link_device.error_server_unreachable'], [502, 'pairing_unavailable', 'link_device.error_pairing_unavailable'], + [400, 'insecure_server', 'link_device.error_insecure_server'], [400, 'invalid_request', 'link_device.error'], [500, 'something_else', 'link_device.error'], ])('maps %i %s to %s', async (status, error, key) => { diff --git a/components/settings/account-security-settings.tsx b/components/settings/account-security-settings.tsx index 161bbecb9..78f1b0f42 100644 --- a/components/settings/account-security-settings.tsx +++ b/components/settings/account-security-settings.tsx @@ -1161,6 +1161,9 @@ export function LinkDeviceSection() { case 'pairing_unavailable': backToIdle(t('link_device.error_pairing_unavailable')); return; + case 'insecure_server': + backToIdle(t('link_device.error_insecure_server')); + return; case 'too_many_attempts': setTotp(''); fail(t('link_device.error_too_many_attempts')); diff --git a/lib/__tests__/pair-create-route.test.ts b/lib/__tests__/pair-create-route.test.ts index 0460fb7ea..2509a68a0 100644 --- a/lib/__tests__/pair-create-route.test.ts +++ b/lib/__tests__/pair-create-route.test.ts @@ -834,3 +834,19 @@ describe('pair/create after the security review', () => { expect((await create({ slot: 5, password: WRONG_PASSWORD })).status).toBe(429); }); }); + +describe('pair/create for a server the app refuses', () => { + it('refuses a plain-http mail server before any step-up', async () => { + handler = mailServer({ base: 'http://mail.lan' }); + signIn(0, { serverUrl: 'http://mail.lan' }); + expect(await create({ password: PASSWORD })).toMatchObject({ status: 400, body: { error: 'insecure_server' } }); + expect(calls).toEqual([]); + }); + + it('allows loopback http, as the app does for development', async () => { + handler = mailServer({ base: 'http://localhost:8080' }); + signIn(0, { serverUrl: 'http://localhost:8080' }); + config.jmapServerUrl = 'http://localhost:8080'; + expect((await create({ password: PASSWORD })).status).toBe(200); + }); +}); diff --git a/lib/auth/pair-bundle.ts b/lib/auth/pair-bundle.ts index f9aa4dd20..c6f066a71 100644 --- a/lib/auth/pair-bundle.ts +++ b/lib/auth/pair-bundle.ts @@ -59,6 +59,14 @@ function isLoopbackHttp(url: string): boolean { return url.toLowerCase().startsWith('http://') && (host === 'localhost' || host === '127.0.0.1' || host === '10.0.2.2'); } +/** + * Whether the app will connect to this JMAP server at all: https, or loopback + * http for development (the app's own rule for a paired `server_url`). + */ +export function appAcceptsServerUrl(serverUrl: string): boolean { + return serverUrl.toLowerCase().startsWith('https://') || isLoopbackHttp(serverUrl); +} + /** * Mirrors the app's `isAcceptableTokenEndpoint` (src/lib/oauth.ts): https (or * loopback http for development), on the host family of the JMAP server or diff --git a/locales/ar/common.json b/locales/ar/common.json index 97f073946..49d9a5603 100644 --- a/locales/ar/common.json +++ b/locales/ar/common.json @@ -1752,7 +1752,8 @@ "success_title": "تم تسجيل الدخول على هاتفك", "success_body": "يمكنك إغلاق هذه الصفحة. لربط جهاز آخر، اعرض رمزًا جديدًا.", "link_another": "ربط جهاز آخر", - "use_sso": "استخدم تسجيل الدخول الموحّد بدلاً من ذلك" + "use_sso": "استخدم تسجيل الدخول الموحّد بدلاً من ذلك", + "error_insecure_server": "يتصل تطبيق الهاتف بخوادم البريد عبر https فقط، وهذا الخادم يستخدم http." }, "public_keys": { "name_label": "اسم المفتاح العام", diff --git a/locales/ca/common.json b/locales/ca/common.json index fcc407662..20ed73845 100644 --- a/locales/ca/common.json +++ b/locales/ca/common.json @@ -1752,7 +1752,8 @@ "success_title": "Sessió iniciada al telèfon", "success_body": "Podeu tancar aquesta pàgina. Per enllaçar un altre dispositiu, mostreu un codi nou.", "link_another": "Enllaça un altre dispositiu", - "use_sso": "Utilitza l'inici de sessió únic" + "use_sso": "Utilitza l'inici de sessió únic", + "error_insecure_server": "L'aplicació mòbil només es connecta a servidors de correu per https, i aquest fa servir http." }, "public_keys": { "name_label": "Nom de la clau pública", diff --git a/locales/cs/common.json b/locales/cs/common.json index a4a428374..a2921a420 100644 --- a/locales/cs/common.json +++ b/locales/cs/common.json @@ -1745,7 +1745,8 @@ "success_title": "Přihlášeno v telefonu", "success_body": "Tuto stránku můžete zavřít. Chcete-li propojit další zařízení, zobrazte nový kód.", "link_another": "Propojit další zařízení", - "use_sso": "Použít místo toho jednotné přihlášení" + "use_sso": "Použít místo toho jednotné přihlášení", + "error_insecure_server": "Mobilní aplikace se k poštovním serverům připojuje jen přes https a tento server používá http." }, "public_keys": { "name_label": "Název veřejného klíče", diff --git a/locales/da/common.json b/locales/da/common.json index a501646a3..bf399bcaf 100644 --- a/locales/da/common.json +++ b/locales/da/common.json @@ -1748,7 +1748,8 @@ "success_title": "Logget ind på din telefon", "success_body": "Du kan lukke denne side. Vis en ny kode for at tilknytte en anden enhed.", "link_another": "Tilknyt en anden enhed", - "use_sso": "Brug single sign-on i stedet" + "use_sso": "Brug single sign-on i stedet", + "error_insecure_server": "Mobilappen forbinder kun til mailservere via https, og denne bruger http." }, "public_keys": { "name_label": "Navn på offentlig nøgle", diff --git a/locales/de/common.json b/locales/de/common.json index 6ea172add..83b17bba7 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -1745,7 +1745,8 @@ "success_title": "Auf Ihrem Smartphone angemeldet", "success_body": "Sie können diese Seite schließen. Um ein weiteres Gerät zu verknüpfen, lassen Sie einen neuen Code anzeigen.", "link_another": "Weiteres Gerät verknüpfen", - "use_sso": "Stattdessen Single Sign-On verwenden" + "use_sso": "Stattdessen Single Sign-On verwenden", + "error_insecure_server": "Die App verbindet sich nur über https mit Mailservern, und dieser verwendet http." }, "public_keys": { "name_label": "Name des öffentlichen Schlüssels", diff --git a/locales/en/common.json b/locales/en/common.json index 34ec35344..e70dede26 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -1759,7 +1759,8 @@ "success_title": "Signed in on your phone", "success_body": "You can close this page. To link another device, show a new code.", "link_another": "Link another device", - "use_sso": "Use single sign-on instead" + "use_sso": "Use single sign-on instead", + "error_insecure_server": "The mobile app only connects to mail servers over https, and this one uses http." } }, "identities": { diff --git a/locales/es/common.json b/locales/es/common.json index 9b126fa23..a682b1f3d 100644 --- a/locales/es/common.json +++ b/locales/es/common.json @@ -1745,7 +1745,8 @@ "success_title": "Sesión iniciada en su teléfono", "success_body": "Puede cerrar esta página. Para vincular otro dispositivo, muestre un código nuevo.", "link_another": "Vincular otro dispositivo", - "use_sso": "Usar el inicio de sesión único" + "use_sso": "Usar el inicio de sesión único", + "error_insecure_server": "La aplicación móvil solo se conecta a servidores de correo por https, y este usa http." }, "public_keys": { "name_label": "Nombre de la clave pública", diff --git a/locales/fa/common.json b/locales/fa/common.json index 23c71aad9..816728d55 100644 --- a/locales/fa/common.json +++ b/locales/fa/common.json @@ -1752,7 +1752,8 @@ "success_title": "ورود در گوشی شما انجام شد", "success_body": "می‌توانید این صفحه را ببندید. برای اتصال دستگاه دیگر، کد جدیدی نمایش دهید.", "link_another": "اتصال دستگاه دیگر", - "use_sso": "به‌جای آن از ورود یکپارچه استفاده کنید" + "use_sso": "به‌جای آن از ورود یکپارچه استفاده کنید", + "error_insecure_server": "برنامه موبایل فقط از طریق https به سرورهای ایمیل وصل می‌شود و این سرور از http استفاده می‌کند." }, "public_keys": { "name_label": "نام کلید عمومی", diff --git a/locales/fr/common.json b/locales/fr/common.json index d070ab22d..c52564698 100644 --- a/locales/fr/common.json +++ b/locales/fr/common.json @@ -1745,7 +1745,8 @@ "success_title": "Connecté sur votre téléphone", "success_body": "Vous pouvez fermer cette page. Pour associer un autre appareil, affichez un nouveau code.", "link_another": "Associer un autre appareil", - "use_sso": "Utiliser plutôt l'authentification unique" + "use_sso": "Utiliser plutôt l'authentification unique", + "error_insecure_server": "L'application mobile ne se connecte aux serveurs de messagerie qu'en https, et celui-ci utilise http." }, "public_keys": { "name_label": "Nom de la clé publique", diff --git a/locales/he/common.json b/locales/he/common.json index a5682535f..fee06c9d0 100644 --- a/locales/he/common.json +++ b/locales/he/common.json @@ -1710,7 +1710,8 @@ "success_title": "ההתחברות בטלפון הושלמה", "success_body": "אפשר לסגור את הדף הזה. כדי לקשר מכשיר נוסף, הצג קוד חדש.", "link_another": "קשר מכשיר נוסף", - "use_sso": "השתמש בכניסה יחידה במקום" + "use_sso": "השתמש בכניסה יחידה במקום", + "error_insecure_server": "האפליקציה מתחברת לשרתי דואר רק ב-https, והשרת הזה משתמש ב-http." }, "public_keys": { "name_label": "שם המפתח הציבורי", diff --git a/locales/hu/common.json b/locales/hu/common.json index 9278dbcf7..ed432fab2 100644 --- a/locales/hu/common.json +++ b/locales/hu/common.json @@ -1748,7 +1748,8 @@ "success_title": "Bejelentkezve a telefonodon", "success_body": "Bezárhatod ezt az oldalt. Másik eszköz összekapcsolásához jeleníts meg egy új kódot.", "link_another": "Másik eszköz összekapcsolása", - "use_sso": "Egyszeri bejelentkezés használata helyette" + "use_sso": "Egyszeri bejelentkezés használata helyette", + "error_insecure_server": "A mobilalkalmazás csak https-en keresztül csatlakozik levelezőszerverekhez, ez pedig http-t használ." }, "public_keys": { "name_label": "Nyilvános kulcs neve", diff --git a/locales/it/common.json b/locales/it/common.json index 32a958483..b475b4db3 100644 --- a/locales/it/common.json +++ b/locales/it/common.json @@ -1745,7 +1745,8 @@ "success_title": "Accesso effettuato sul telefono", "success_body": "Puoi chiudere questa pagina. Per collegare un altro dispositivo, mostra un nuovo codice.", "link_another": "Collega un altro dispositivo", - "use_sso": "Usa invece l'accesso unico (SSO)" + "use_sso": "Usa invece l'accesso unico (SSO)", + "error_insecure_server": "L'app mobile si collega ai server di posta solo tramite https, e questo usa http." }, "public_keys": { "name_label": "Nome della chiave pubblica", diff --git a/locales/ja/common.json b/locales/ja/common.json index 391a952d8..7c7e63392 100644 --- a/locales/ja/common.json +++ b/locales/ja/common.json @@ -1745,7 +1745,8 @@ "success_title": "スマートフォンでサインインしました", "success_body": "このページは閉じてかまいません。別のデバイスを連携するには、新しいコードを表示してください。", "link_another": "別のデバイスを連携", - "use_sso": "代わりにシングルサインオンを使う" + "use_sso": "代わりにシングルサインオンを使う", + "error_insecure_server": "モバイルアプリは https のメールサーバーにしか接続できませんが、このサーバーは http を使っています。" }, "public_keys": { "name_label": "公開鍵の名前", diff --git a/locales/ko/common.json b/locales/ko/common.json index a11c5a2fb..87c7d8104 100644 --- a/locales/ko/common.json +++ b/locales/ko/common.json @@ -1745,7 +1745,8 @@ "success_title": "휴대폰에서 로그인되었습니다", "success_body": "이 페이지를 닫아도 됩니다. 다른 기기를 연결하려면 새 코드를 표시하세요.", "link_another": "다른 기기 연결", - "use_sso": "대신 SSO(통합 로그인) 사용" + "use_sso": "대신 SSO(통합 로그인) 사용", + "error_insecure_server": "모바일 앱은 https로만 메일 서버에 연결하는데, 이 서버는 http를 사용합니다." }, "public_keys": { "name_label": "공개 키 이름", diff --git a/locales/lv/common.json b/locales/lv/common.json index cfeb532f8..d77c2451c 100644 --- a/locales/lv/common.json +++ b/locales/lv/common.json @@ -1745,7 +1745,8 @@ "success_title": "Pierakstīšanās tālrunī izdevās", "success_body": "Varat aizvērt šo lapu. Lai saistītu citu ierīci, parādiet jaunu kodu.", "link_another": "Saistīt citu ierīci", - "use_sso": "Tā vietā izmantot vienoto pieteikšanos" + "use_sso": "Tā vietā izmantot vienoto pieteikšanos", + "error_insecure_server": "Mobilā lietotne ar pasta serveriem savienojas tikai caur https, bet šis izmanto http." }, "public_keys": { "name_label": "Publiskās atslēgas nosaukums", diff --git a/locales/mn/common.json b/locales/mn/common.json index 994e2bb65..25d8b17b5 100644 --- a/locales/mn/common.json +++ b/locales/mn/common.json @@ -1759,7 +1759,8 @@ "success_title": "Утсан дээрээ нэвтэрлээ", "success_body": "Та энэ хуудсыг хааж болно. Өөр төхөөрөмж холбохын тулд шинэ код харуулна уу.", "link_another": "Өөр төхөөрөмж холбох", - "use_sso": "Оронд нь нэгдсэн нэвтрэлт ашиглах" + "use_sso": "Оронд нь нэгдсэн нэвтрэлт ашиглах", + "error_insecure_server": "Гар утасны апп зөвхөн https-ээр мэйл серверт холбогддог бөгөөд энэ сервер http ашиглаж байна." } }, "identities": { diff --git a/locales/nb/common.json b/locales/nb/common.json index b076bd678..1a761c3da 100644 --- a/locales/nb/common.json +++ b/locales/nb/common.json @@ -1759,7 +1759,8 @@ "success_title": "Pålogget på telefonen", "success_body": "Du kan lukke denne siden. Vis en ny kode for å koble til en annen enhet.", "link_another": "Koble til en annen enhet", - "use_sso": "Bruk enkel pålogging i stedet" + "use_sso": "Bruk enkel pålogging i stedet", + "error_insecure_server": "Mobilappen kobler bare til e-postservere over https, og denne bruker http." } }, "identities": { diff --git a/locales/nl/common.json b/locales/nl/common.json index 3da9b306d..d73a967f9 100644 --- a/locales/nl/common.json +++ b/locales/nl/common.json @@ -1745,7 +1745,8 @@ "success_title": "Ingelogd op uw telefoon", "success_body": "U kunt deze pagina sluiten. Toon een nieuwe code om nog een apparaat te koppelen.", "link_another": "Nog een apparaat koppelen", - "use_sso": "In plaats daarvan eenmalige aanmelding gebruiken" + "use_sso": "In plaats daarvan eenmalige aanmelding gebruiken", + "error_insecure_server": "De mobiele app maakt alleen via https verbinding met mailservers, en deze gebruikt http." }, "public_keys": { "name_label": "Naam van openbare sleutel", diff --git a/locales/pl/common.json b/locales/pl/common.json index 19267298a..c23f838a6 100644 --- a/locales/pl/common.json +++ b/locales/pl/common.json @@ -1745,7 +1745,8 @@ "success_title": "Zalogowano na telefonie", "success_body": "Możesz zamknąć tę stronę. Aby połączyć kolejne urządzenie, pokaż nowy kod.", "link_another": "Połącz kolejne urządzenie", - "use_sso": "Zamiast tego użyj logowania jednokrotnego" + "use_sso": "Zamiast tego użyj logowania jednokrotnego", + "error_insecure_server": "Aplikacja mobilna łączy się z serwerami poczty tylko przez https, a ten używa http." }, "public_keys": { "name_label": "Nazwa klucza publicznego", diff --git a/locales/pt/common.json b/locales/pt/common.json index b0670b624..aefe1c55b 100644 --- a/locales/pt/common.json +++ b/locales/pt/common.json @@ -1745,7 +1745,8 @@ "success_title": "Conectado no seu celular", "success_body": "Você pode fechar esta página. Para vincular outro dispositivo, mostre um novo código.", "link_another": "Vincular outro dispositivo", - "use_sso": "Usar o início de sessão único" + "use_sso": "Usar o início de sessão único", + "error_insecure_server": "A aplicação móvel só se liga a servidores de correio por https, e este usa http." }, "public_keys": { "name_label": "Nome da chave pública", diff --git a/locales/ro/common.json b/locales/ro/common.json index 64112f5fc..3cfb9b78a 100644 --- a/locales/ro/common.json +++ b/locales/ro/common.json @@ -1752,7 +1752,8 @@ "success_title": "Conectat pe telefon", "success_body": "Puteți închide această pagină. Pentru a asocia un alt dispozitiv, afișați un cod nou.", "link_another": "Asociați alt dispozitiv", - "use_sso": "Folosește autentificarea unică în schimb" + "use_sso": "Folosește autentificarea unică în schimb", + "error_insecure_server": "Aplicația mobilă se conectează la serverele de e-mail doar prin https, iar acesta folosește http." }, "public_keys": { "name_label": "Numele cheii publice", diff --git a/locales/ru/common.json b/locales/ru/common.json index 0f9cb3e7c..4df16d994 100644 --- a/locales/ru/common.json +++ b/locales/ru/common.json @@ -1745,7 +1745,8 @@ "success_title": "Вход на телефоне выполнен", "success_body": "Эту страницу можно закрыть. Чтобы привязать ещё одно устройство, покажите новый код.", "link_another": "Привязать ещё одно устройство", - "use_sso": "Использовать единый вход" + "use_sso": "Использовать единый вход", + "error_insecure_server": "Мобильное приложение подключается к почтовым серверам только по https, а этот сервер использует http." }, "public_keys": { "name_label": "Название открытого ключа", diff --git a/locales/sk/common.json b/locales/sk/common.json index e870421e5..dfa41380b 100644 --- a/locales/sk/common.json +++ b/locales/sk/common.json @@ -1752,7 +1752,8 @@ "success_title": "Prihlásené v telefóne", "success_body": "Túto stránku môžete zavrieť. Ak chcete prepojiť ďalšie zariadenie, zobrazte nový kód.", "link_another": "Prepojiť ďalšie zariadenie", - "use_sso": "Použiť namiesto toho jednotné prihlásenie" + "use_sso": "Použiť namiesto toho jednotné prihlásenie", + "error_insecure_server": "Mobilná aplikácia sa k poštovým serverom pripája len cez https a tento server používa http." }, "public_keys": { "name_label": "Názov verejného kľúča", diff --git a/locales/tr/common.json b/locales/tr/common.json index 82668b033..52484ab4e 100644 --- a/locales/tr/common.json +++ b/locales/tr/common.json @@ -1745,7 +1745,8 @@ "success_title": "Telefonunuzda oturum açıldı", "success_body": "Bu sayfayı kapatabilirsiniz. Başka bir cihaz bağlamak için yeni bir kod gösterin.", "link_another": "Başka bir cihaz bağla", - "use_sso": "Bunun yerine çoklu oturum açmayı kullan" + "use_sso": "Bunun yerine çoklu oturum açmayı kullan", + "error_insecure_server": "Mobil uygulama posta sunucularına yalnızca https üzerinden bağlanır, bu sunucu ise http kullanıyor." }, "public_keys": { "name_label": "Ortak anahtar adı", diff --git a/locales/uk/common.json b/locales/uk/common.json index 3517837f1..c048386c6 100644 --- a/locales/uk/common.json +++ b/locales/uk/common.json @@ -1745,7 +1745,8 @@ "success_title": "Вхід на телефоні виконано", "success_body": "Цю сторінку можна закрити. Щоб прив'язати ще один пристрій, покажіть новий код.", "link_another": "Прив'язати ще один пристрій", - "use_sso": "Натомість використати єдиний вхід" + "use_sso": "Натомість використати єдиний вхід", + "error_insecure_server": "Мобільний застосунок підключається до поштових серверів лише через https, а цей сервер використовує http." }, "public_keys": { "name_label": "Назва відкритого ключа", diff --git a/locales/zh-TW/common.json b/locales/zh-TW/common.json index 20e53208f..41db3d5b8 100644 --- a/locales/zh-TW/common.json +++ b/locales/zh-TW/common.json @@ -1759,7 +1759,8 @@ "success_title": "已在手機上登入", "success_body": "你可以關閉此頁面。若要連結其他裝置,請顯示新的 QR Code。", "link_another": "連結其他裝置", - "use_sso": "改用單一登入" + "use_sso": "改用單一登入", + "error_insecure_server": "行動應用程式只透過 https 連線到郵件伺服器,而此伺服器使用的是 http。" } }, "identities": { diff --git a/locales/zh/common.json b/locales/zh/common.json index b2b06d85f..9396bac93 100644 --- a/locales/zh/common.json +++ b/locales/zh/common.json @@ -1745,7 +1745,8 @@ "success_title": "已在手机上登录", "success_body": "你可以关闭此页面。如需关联其他设备,请显示新的二维码。", "link_another": "关联其他设备", - "use_sso": "改用单点登录" + "use_sso": "改用单点登录", + "error_insecure_server": "移动应用只通过 https 连接邮件服务器,而此服务器使用的是 http。" }, "public_keys": { "name_label": "公钥名称",