feat(android): platform trust for public gateway certs and manual fingerprint pinning (#110976)

Publicly-CA-valid gateway hosts (e.g. Tailscale Funnel with Let's Encrypt)
no longer force fingerprint pinning: a real platform-trust handshake with
HTTPS hostname verification and SNI connects without prompting, ending the
changed-pin re-prompt on every cert renewal. Candidate gating excludes
.local, IP literals, and single-label hosts so LAN endpoints keep pinning.
Existing pins stay authoritative: a valid public chain never silently clears
a stored pin - the changed-pin prompt gains an explicit one-time 'Use system
trust' switch instead. Discovered endpoints still require a stored pin for
reconnect eligibility (discovery data is attacker-controllable). When the
TLS probe cannot capture a certificate, the trust dialog now accepts an
out-of-band SHA-256 fingerprint paste (sha256:/colon tolerant, 64-hex
validated) which is then enforced on connect. Malformed stored pins now
fail closed instead of silently degrading. Both probe attempts share one
connect+handshake budget so stalled hosts cannot double the probe latency.
This commit is contained in:
Peter Steinberger
2026-07-19 00:48:06 -07:00
committed by GitHub
parent 716f507564
commit 33b50089cd
53 changed files with 2063 additions and 509 deletions
File diff suppressed because it is too large Load Diff
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "تعذّر تشغيل الكاميرا. اختر صورة QR من المعرض أو أدخل رمز الإعداد يدويًا."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "تعذّرت قراءة شهادة Gateway تلقائيًا. الصق بصمة SHA-256 التي حصلت عليها من مضيف Gateway."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "يقدّم Gateway هذا الآن شهادة موثوقة من هذا الجهاز."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "بصمة SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "الوثوق"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "استخدام ثقة النظام"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "إغلاق Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "تعذّرت قراءة شهادة Gateway تلقائيًا. الصق بصمة SHA-256 التي حصلت عليها من مضيف Gateway."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "يقدّم Gateway هذا الآن شهادة موثوقة من هذا الجهاز."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "بصمة SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "استخدام ثقة النظام"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Die Kamera konnte nicht gestartet werden. Wähle ein QR-Bild aus der Galerie oder gib den Einrichtungscode manuell ein."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Das Gateway-Zertifikat konnte nicht automatisch gelesen werden. Fügen Sie den auf dem Gateway-Host ermittelten SHA-256-Fingerabdruck ein."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Dieses Gateway verwendet jetzt ein Zertifikat, dem dieses Gerät vertraut."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "SHA-256-Fingerabdruck"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Vertrauen"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Systemvertrauen verwenden"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Canvas schließen"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Das Gateway-Zertifikat konnte nicht automatisch gelesen werden. Fügen Sie den auf dem Gateway-Host ermittelten SHA-256-Fingerabdruck ein."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Dieses Gateway verwendet jetzt ein Zertifikat, dem dieses Gerät vertraut."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "SHA-256-Fingerabdruck"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Systemvertrauen verwenden"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "No se pudo iniciar la cámara. Selecciona una imagen QR de la galería o introduce manualmente el código de configuración."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "No se pudo leer automáticamente el certificado del gateway. Pega la huella digital SHA-256 obtenida en el host del gateway."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Este gateway ahora presenta un certificado en el que confía este dispositivo."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "Huella digital SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Confiar"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Usar la confianza del sistema"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Cerrar Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "No se pudo leer automáticamente el certificado del gateway. Pega la huella digital SHA-256 obtenida en el host del gateway."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Este gateway ahora presenta un certificado en el que confía este dispositivo."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "Huella digital SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Usar la confianza del sistema"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "راه‌اندازی دوربین ممکن نبود. یک تصویر QR از گالری انتخاب کنید یا کد راه‌اندازی را به‌صورت دستی وارد کنید."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "گواهی Gateway به‌طور خودکار قابل خواندن نبود. اثر انگشت SHA-256 دریافت‌شده در میزبان Gateway را جای‌گذاری کنید."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "این Gateway اکنون گواهی‌ای ارائه می‌کند که مورد اعتماد این دستگاه است."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "اثر انگشت SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "اعتماد"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "استفاده از اعتماد سیستم"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "بستن Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "گواهی Gateway به‌طور خودکار قابل خواندن نبود. اثر انگشت SHA-256 دریافت‌شده در میزبان Gateway را جای‌گذاری کنید."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "این Gateway اکنون گواهی‌ای ارائه می‌کند که مورد اعتماد این دستگاه است."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "اثر انگشت SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "استفاده از اعتماد سیستم"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Impossible de démarrer lappareil photo. Choisissez une image du code QR dans la galerie ou saisissez manuellement le code de configuration."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Le certificat du Gateway na pas pu être lu automatiquement. Collez lempreinte SHA-256 obtenue sur lhôte du Gateway."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Ce Gateway présente désormais un certificat approuvé par cet appareil."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "Empreinte SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Faire confiance"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Utiliser la confiance du système"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Fermer Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Le certificat du Gateway na pas pu être lu automatiquement. Collez lempreinte SHA-256 obtenue sur lhôte du Gateway."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Ce Gateway présente désormais un certificat approuvé par cet appareil."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "Empreinte SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Utiliser la confiance du système"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "कैमरा शुरू नहीं किया जा सका। गैलरी से QR इमेज चुनें या सेटअप कोड मैन्युअल रूप से दर्ज करें।"
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Gateway प्रमाणपत्र को स्वचालित रूप से पढ़ा नहीं जा सका। Gateway होस्ट पर प्राप्त SHA-256 फ़िंगरप्रिंट पेस्ट करें।"
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "यह Gateway अब इस डिवाइस द्वारा विश्वसनीय प्रमाणपत्र प्रस्तुत करता है।"
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "SHA-256 फ़िंगरप्रिंट"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "भरोसा करें"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "सिस्टम विश्वसनीयता का उपयोग करें"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Canvas बंद करें"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Gateway प्रमाणपत्र को स्वचालित रूप से पढ़ा नहीं जा सका। Gateway होस्ट पर प्राप्त SHA-256 फ़िंगरप्रिंट पेस्ट करें।"
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "यह Gateway अब इस डिवाइस द्वारा विश्वसनीय प्रमाणपत्र प्रस्तुत करता है।"
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "SHA-256 फ़िंगरप्रिंट"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "सिस्टम विश्वसनीयता का उपयोग करें"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Kamera tidak dapat dimulai. Pilih gambar QR dari galeri atau masukkan kode penyiapan secara manual."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Sertifikat Gateway tidak dapat dibaca secara otomatis. Tempelkan sidik jari SHA-256 yang diperoleh di host Gateway."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Gateway ini sekarang menyajikan sertifikat yang dipercaya oleh perangkat ini."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "Sidik jari SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Percayai"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Gunakan kepercayaan sistem"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Tutup Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Sertifikat Gateway tidak dapat dibaca secara otomatis. Tempelkan sidik jari SHA-256 yang diperoleh di host Gateway."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Gateway ini sekarang menyajikan sertifikat yang dipercaya oleh perangkat ini."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "Sidik jari SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Gunakan kepercayaan sistem"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Impossibile avviare la fotocamera. Scegli un'immagine QR dalla galleria oppure inserisci manualmente il codice di configurazione."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Non è stato possibile leggere automaticamente il certificato del Gateway. Incolla l'impronta digitale SHA-256 ottenuta sull'host del Gateway."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Questo Gateway ora presenta un certificato considerato attendibile da questo dispositivo."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "Impronta digitale SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Autorizza"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Usa l'attendibilità di sistema"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Chiudi Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Non è stato possibile leggere automaticamente il certificato del Gateway. Incolla l'impronta digitale SHA-256 ottenuta sull'host del Gateway."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Questo Gateway ora presenta un certificato considerato attendibile da questo dispositivo."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "Impronta digitale SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Usa l'attendibilità di sistema"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "カメラを起動できませんでした。ギャラリーからQR画像を選択するか、セットアップコードを手動で入力してください。"
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Gateway証明書を自動的に読み取れませんでした。Gatewayホストで取得したSHA-256フィンガープリントを貼り付けてください。"
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "このGatewayは現在、このデバイスによって信頼されている証明書を提示しています。"
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "SHA-256フィンガープリント"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "信頼"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "システムの信頼設定を使用"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Canvas を閉じる"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Gateway証明書を自動的に読み取れませんでした。Gatewayホストで取得したSHA-256フィンガープリントを貼り付けてください。"
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "このGatewayは現在、このデバイスによって信頼されている証明書を提示しています。"
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "SHA-256フィンガープリント"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "システムの信頼設定を使用"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "카메라를 시작할 수 없습니다. 갤러리에서 QR 이미지를 선택하거나 설정 코드를 직접 입력하세요."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Gateway 인증서를 자동으로 읽을 수 없습니다. Gateway 호스트에서 확인한 SHA-256 지문을 붙여넣으세요."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "이제 이 Gateway는 이 기기에서 신뢰하는 인증서를 제공합니다."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "SHA-256 지문"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "신뢰"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "시스템 신뢰 사용"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Canvas 닫기"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Gateway 인증서를 자동으로 읽을 수 없습니다. Gateway 호스트에서 확인한 SHA-256 지문을 붙여넣으세요."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "이제 이 Gateway는 이 기기에서 신뢰하는 인증서를 제공합니다."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "SHA-256 지문"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "시스템 신뢰 사용"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Kan de camera niet starten. Kies een QR-afbeelding uit de galerij of voer de installatiecode handmatig in."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Het Gateway-certificaat kon niet automatisch worden gelezen. Plak de SHA-256-vingerafdruk die op de Gateway-host is verkregen."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Deze Gateway gebruikt nu een certificaat dat door dit apparaat wordt vertrouwd."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "SHA-256-vingerafdruk"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Vertrouwen"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Systeemvertrouwen gebruiken"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Canvas sluiten"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Het Gateway-certificaat kon niet automatisch worden gelezen. Plak de SHA-256-vingerafdruk die op de Gateway-host is verkregen."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Deze Gateway gebruikt nu een certificaat dat door dit apparaat wordt vertrouwd."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "SHA-256-vingerafdruk"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Systeemvertrouwen gebruiken"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Nie udało się uruchomić aparatu. Wybierz obraz kodu QR z galerii lub wprowadź kod konfiguracji ręcznie."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Nie udało się automatycznie odczytać certyfikatu Gateway. Wklej odcisk SHA-256 uzyskany na hoście Gateway."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Ten Gateway używa teraz certyfikatu zaufanego przez to urządzenie."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "Odcisk SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Zaufaj"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Użyj zaufania systemowego"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Zamknij Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Nie udało się automatycznie odczytać certyfikatu Gateway. Wklej odcisk SHA-256 uzyskany na hoście Gateway."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Ten Gateway używa teraz certyfikatu zaufanego przez to urządzenie."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "Odcisk SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Użyj zaufania systemowego"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Não foi possível iniciar a câmera. Escolha uma imagem de QR na galeria ou insira o código de configuração manualmente."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Não foi possível ler automaticamente o certificado do Gateway. Cole a impressão digital SHA-256 obtida no host do Gateway."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Este Gateway agora apresenta um certificado confiável para este dispositivo."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "Impressão digital SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Confiar"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Usar confiança do sistema"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Fechar Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Não foi possível ler automaticamente o certificado do Gateway. Cole a impressão digital SHA-256 obtida no host do Gateway."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Este Gateway agora apresenta um certificado confiável para este dispositivo."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "Impressão digital SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Usar confiança do sistema"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Не удалось запустить камеру. Выберите изображение QR-кода из галереи или введите код настройки вручную."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Не удалось автоматически прочитать сертификат Gateway. Вставьте отпечаток SHA-256, полученный на хосте Gateway."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Теперь этот Gateway предоставляет сертификат, которому доверяет это устройство."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "Отпечаток SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Доверять"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Использовать системное доверие"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Закрыть Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Не удалось автоматически прочитать сертификат Gateway. Вставьте отпечаток SHA-256, полученный на хосте Gateway."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Теперь этот Gateway предоставляет сертификат, которому доверяет это устройство."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "Отпечаток SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Использовать системное доверие"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Det gick inte att starta kameran. Välj en QR-bild från galleriet eller ange konfigurationskoden manuellt."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Gateway-certifikatet kunde inte läsas automatiskt. Klistra in SHA-256-fingeravtrycket som hämtats på Gateway-värden."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Denna Gateway använder nu ett certifikat som den här enheten litar på."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "SHA-256-fingeravtryck"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Lita på"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Använd systemets förtroende"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Stäng Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Gateway-certifikatet kunde inte läsas automatiskt. Klistra in SHA-256-fingeravtrycket som hämtats på Gateway-värden."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Denna Gateway använder nu ett certifikat som den här enheten litar på."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "SHA-256-fingeravtryck"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Använd systemets förtroende"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "ไม่สามารถเปิดกล้องได้ โปรดเลือกรูปภาพคิวอาร์จากแกลเลอรีหรือป้อนรหัสตั้งค่าด้วยตนเอง"
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "ไม่สามารถอ่านใบรับรองของ Gateway โดยอัตโนมัติได้ ให้วางลายนิ้วมือ SHA-256 ที่ได้รับจากโฮสต์ Gateway"
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "ขณะนี้ Gateway นี้แสดงใบรับรองที่อุปกรณ์นี้เชื่อถือ"
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "ลายนิ้วมือ SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "เชื่อถือ"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "ใช้ความเชื่อถือของระบบ"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "ปิด Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "ไม่สามารถอ่านใบรับรองของ Gateway โดยอัตโนมัติได้ ให้วางลายนิ้วมือ SHA-256 ที่ได้รับจากโฮสต์ Gateway"
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "ขณะนี้ Gateway นี้แสดงใบรับรองที่อุปกรณ์นี้เชื่อถือ"
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "ลายนิ้วมือ SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "ใช้ความเชื่อถือของระบบ"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Kamera başlatılamadı. Galeriden bir QR görseli seçin veya kurulum kodunu manuel olarak girin."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Gateway sertifikası otomatik olarak okunamadı. Gateway ana bilgisayarından alınan SHA-256 parmak izini yapıştırın."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Bu Gateway artık bu cihazın güvendiği bir sertifika sunuyor."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "SHA-256 parmak izi"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Güven"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Sistem güvenini kullan"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Canvas'ı Kapat"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Gateway sertifikası otomatik olarak okunamadı. Gateway ana bilgisayarından alınan SHA-256 parmak izini yapıştırın."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Bu Gateway artık bu cihazın güvendiği bir sertifika sunuyor."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "SHA-256 parmak izi"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Sistem güvenini kullan"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Не вдалося запустити камеру. Виберіть зображення QR-коду з галереї або введіть код налаштування вручну."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Не вдалося автоматично прочитати сертифікат Gateway. Вставте відбиток SHA-256, отриманий на хості Gateway."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Тепер цей Gateway надає сертифікат, якому довіряє цей пристрій."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "Відбиток SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Довіряти"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Використовувати системну довіру"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Закрити Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Не вдалося автоматично прочитати сертифікат Gateway. Вставте відбиток SHA-256, отриманий на хості Gateway."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Тепер цей Gateway надає сертифікат, якому довіряє цей пристрій."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "Відбиток SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Використовувати системну довіру"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "Không thể khởi động camera. Hãy chọn hình ảnh mã QR từ thư viện hoặc nhập mã thiết lập theo cách thủ công."
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Không thể tự động đọc chứng chỉ của Gateway. Hãy dán dấu vân tay SHA-256 lấy được trên máy chủ Gateway."
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Gateway này hiện cung cấp chứng chỉ được thiết bị này tin cậy."
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "Dấu vân tay SHA-256"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "Tin cậy"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "Sử dụng độ tin cậy của hệ thống"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "Đóng Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "Không thể tự động đọc chứng chỉ của Gateway. Hãy dán dấu vân tay SHA-256 lấy được trên máy chủ Gateway."
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "Gateway này hiện cung cấp chứng chỉ được thiết bị này tin cậy."
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "Dấu vân tay SHA-256"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "Sử dụng độ tin cậy của hệ thống"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "无法启动相机。请从图库中选择二维码图片,或手动输入设置代码。"
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "无法自动读取 Gateway 证书。请粘贴在 Gateway 主机上获取的 SHA-256 指纹。"
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "此 Gateway 现在提供的证书已受此设备信任。"
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "SHA-256 指纹"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "信任"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "使用系统信任"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "关闭 Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "无法自动读取 Gateway 证书。请粘贴在 Gateway 主机上获取的 SHA-256 指纹。"
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "此 Gateway 现在提供的证书已受此设备信任。"
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "SHA-256 指纹"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "使用系统信任"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
+40
View File
@@ -2603,11 +2603,31 @@
"source": "Could not start the camera. Choose a QR image from gallery or enter the setup code manually.",
"translated": "無法啟動相機。請從相簿選擇 QR 圖片,或手動輸入設定代碼。"
},
{
"id": "native.android.7a18be21a62739bf",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "無法自動讀取 Gateway 憑證。請貼上從 Gateway 主機取得的 SHA-256 指紋。"
},
{
"id": "native.android.aa489429ad39aa39",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "此 Gateway 現在提供的憑證已受此裝置信任。"
},
{
"id": "native.android.b3db82f1162808ad",
"source": "SHA-256 fingerprint",
"translated": "SHA-256 指紋"
},
{
"id": "native.android.9ac2d4498b17d478",
"source": "Trust",
"translated": "信任"
},
{
"id": "native.android.09245320d3878458",
"source": "Use system trust",
"translated": "使用系統信任設定"
},
{
"id": "native.android.e26ee07a1d1911be",
"source": "Cancel",
@@ -5438,6 +5458,26 @@
"source": "Close Canvas",
"translated": "關閉 Canvas"
},
{
"id": "native.android.846fe5afd08b8089",
"source": "The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
"translated": "無法自動讀取 Gateway 憑證。請貼上從 Gateway 主機取得的 SHA-256 指紋。"
},
{
"id": "native.android.b263dca13f55dad9",
"source": "This gateway now presents a certificate trusted by this device.",
"translated": "此 Gateway 現在提供的憑證已受此裝置信任。"
},
{
"id": "native.android.dca0f8814b658170",
"source": "SHA-256 fingerprint",
"translated": "SHA-256 指紋"
},
{
"id": "native.android.bb5d50fcdd5ebafe",
"source": "Use system trust",
"translated": "使用系統信任設定"
},
{
"id": "native.android.3d83e0755437a5f9",
"source": "Overview",
@@ -1238,8 +1238,12 @@ class MainViewModel private constructor(
}
}
fun acceptGatewayTrustPrompt() {
runtimeRef.value?.acceptGatewayTrustPrompt()
fun acceptGatewayTrustPrompt(manualFingerprint: String? = null) {
runtimeRef.value?.acceptGatewayTrustPrompt(manualFingerprint)
}
fun useSystemGatewayTrustPrompt() {
runtimeRef.value?.useSystemGatewayTrustPrompt()
}
fun declineGatewayTrustPrompt() {
@@ -45,12 +45,15 @@ import ai.openclaw.app.gateway.GatewayRequestRejected
import ai.openclaw.app.gateway.GatewaySession
import ai.openclaw.app.gateway.GatewayTlsProbeFailure
import ai.openclaw.app.gateway.GatewayTlsProbeResult
import ai.openclaw.app.gateway.GatewayTlsTrustDecision
import ai.openclaw.app.gateway.GatewayUpdateAvailableSummary
import ai.openclaw.app.gateway.NetworkMonitor
import ai.openclaw.app.gateway.NodeEventSendOutcome
import ai.openclaw.app.gateway.decideGatewayTlsTrust
import ai.openclaw.app.gateway.formatGatewayAuthority
import ai.openclaw.app.gateway.isGatewayTlsSystemTrustCandidate
import ai.openclaw.app.gateway.normalizeGatewayApprovalRequestId
import ai.openclaw.app.gateway.normalizeGatewayTlsFingerprint
import ai.openclaw.app.gateway.normalizeGatewayTlsFingerprintInput
import ai.openclaw.app.gateway.parseChatSendAck
import ai.openclaw.app.gateway.probeGatewayTlsFingerprint
import ai.openclaw.app.i18n.NativeText
@@ -798,9 +801,11 @@ class NodeRuntime private constructor(
*/
data class GatewayTrustPrompt(
val endpoint: GatewayEndpoint,
val fingerprintSha256: String,
val fingerprintSha256: String?,
val auth: GatewayConnectAuth,
val previousFingerprintSha256: String? = null,
val probeFailure: GatewayTlsProbeFailure? = null,
val systemTrustAvailable: Boolean = false,
)
data class VoiceE2eSliceResult(
@@ -3844,43 +3849,47 @@ class NodeRuntime private constructor(
_pendingGatewayTrust.value = null
val tls = connectionManager.resolveTlsParams(endpoint)
if (tls?.required == true) {
val expectedFingerprint =
tls.expectedFingerprint
?.let(::normalizeGatewayTlsFingerprint)
?.takeIf { it.isNotBlank() }
val storedFingerprint = tls.expectedFingerprint
setStandaloneGatewayStatus("Verify gateway TLS fingerprint…")
scope.launch {
val tlsProbe = tlsFingerprintProbe(endpoint.host, endpoint.port)
if (!isCurrentConnectAttempt(connectAttemptId)) return@launch
val fp =
tlsProbe.fingerprintSha256 ?: run {
if (expectedFingerprint == null) {
connectingEndpointStableId = null
setStandaloneGatewayStatus(gatewayTlsProbeFailureMessage(tlsProbe.failure))
} else {
connectAfterTlsCheck(endpoint = endpoint, auth = auth, connectAttemptId = connectAttemptId)
}
return@launch
when (
val decision =
decideGatewayTlsTrust(
storedFingerprint = storedFingerprint,
systemTrustCandidate = isGatewayTlsSystemTrustCandidate(endpoint.host),
probeResult = tlsProbe,
)
) {
GatewayTlsTrustDecision.SystemTrusted -> {
// Automatic platform trust only applies where no user-accepted pin exists.
// Replacing a pin always requires explicit confirmation in the trust prompt.
registerGateway(endpoint, setActive = true)
connectAfterTlsCheck(endpoint = endpoint, auth = auth, connectAttemptId = connectAttemptId)
}
is GatewayTlsTrustDecision.PinnedTrust ->
connectAfterTlsCheck(endpoint = endpoint, auth = auth, connectAttemptId = connectAttemptId)
is GatewayTlsTrustDecision.PromptRequired -> {
decision.probeFailure?.let { setStandaloneGatewayStatus(gatewayTlsProbeFailureMessage(it)) }
publishGatewayTrustPromptIfCurrent(
connectAttemptId = connectAttemptId,
prompt =
GatewayTrustPrompt(
endpoint = endpoint,
fingerprintSha256 = decision.fingerprintSha256,
auth = auth,
previousFingerprintSha256 = decision.previousFingerprintSha256,
probeFailure = decision.probeFailure,
systemTrustAvailable = decision.systemTrustAvailable,
),
)
}
is GatewayTlsTrustDecision.Failed -> {
connectingEndpointStableId = null
setStandaloneGatewayStatus(gatewayTlsProbeFailureMessage(decision.reason))
}
val observedFingerprint =
normalizeGatewayTlsFingerprint(fp)
.takeIf { it.isNotBlank() }
?: fp
val previousFingerprint = expectedFingerprint?.takeUnless { it == observedFingerprint }
if (expectedFingerprint == null || previousFingerprint != null) {
publishGatewayTrustPromptIfCurrent(
connectAttemptId = connectAttemptId,
prompt =
GatewayTrustPrompt(
endpoint = endpoint,
fingerprintSha256 = observedFingerprint,
auth = auth,
previousFingerprintSha256 = previousFingerprint,
),
)
return@launch
}
connectAfterTlsCheck(endpoint = endpoint, auth = auth, connectAttemptId = connectAttemptId)
}
return
}
@@ -4004,13 +4013,30 @@ class NodeRuntime private constructor(
)
}
fun acceptGatewayTrustPrompt() {
fun acceptGatewayTrustPrompt(manualFingerprint: String? = null) {
val prompt = _pendingGatewayTrust.value ?: return
val acceptedFingerprint =
normalizeGatewayTlsFingerprintInput(
prompt.fingerprintSha256 ?: manualFingerprint ?: return,
) ?: return
gatewayLifecycleIntentSeq.incrementAndGet()
launchGatewayLifecycle {
if (_pendingGatewayTrust.value != prompt) return@launchGatewayLifecycle
_pendingGatewayTrust.value = null
prefs.saveGatewayTlsFingerprint(prompt.endpoint.stableId, prompt.fingerprintSha256)
prefs.saveGatewayTlsFingerprint(prompt.endpoint.stableId, acceptedFingerprint)
registerGateway(prompt.endpoint, setActive = true)
beginConnect(endpoint = prompt.endpoint, auth = prompt.auth)
}
}
fun useSystemGatewayTrustPrompt() {
val prompt = _pendingGatewayTrust.value ?: return
if (!prompt.systemTrustAvailable) return
gatewayLifecycleIntentSeq.incrementAndGet()
launchGatewayLifecycle {
if (_pendingGatewayTrust.value != prompt) return@launchGatewayLifecycle
_pendingGatewayTrust.value = null
prefs.clearGatewayTlsFingerprint(prompt.endpoint.stableId)
registerGateway(prompt.endpoint, setActive = true)
beginConnect(endpoint = prompt.endpoint, auth = prompt.auth)
}
@@ -4025,7 +4051,7 @@ class NodeRuntime private constructor(
}
}
private fun gatewayTlsProbeFailureMessage(failure: GatewayTlsProbeFailure?): String =
private fun gatewayTlsProbeFailureMessage(failure: GatewayTlsProbeFailure): String =
when (failure) {
GatewayTlsProbeFailure.TLS_UNAVAILABLE ->
nativeText(
@@ -4035,7 +4061,7 @@ class NodeRuntime private constructor(
nativeText(
"Failed: secure endpoint reached, but TLS fingerprint verification timed out. Check Tailscale Serve or gateway TLS and retry.",
).source
GatewayTlsProbeFailure.ENDPOINT_UNREACHABLE, null ->
GatewayTlsProbeFailure.ENDPOINT_UNREACHABLE ->
nativeText("Failed: couldn't reach the secure gateway endpoint for this host.").source
}
@@ -59,10 +59,106 @@ enum class GatewayTlsProbeFailure {
data class GatewayTlsProbeResult(
val fingerprintSha256: String? = null,
val failure: GatewayTlsProbeFailure? = null,
val systemTrusted: Boolean = false,
)
/** Final trust policy selected before opening gateway sessions. */
sealed interface GatewayTlsTrustDecision {
data object SystemTrusted : GatewayTlsTrustDecision
data class PinnedTrust(
val fingerprintSha256: String,
) : GatewayTlsTrustDecision
data class PromptRequired(
val fingerprintSha256: String?,
val previousFingerprintSha256: String?,
val probeFailure: GatewayTlsProbeFailure? = null,
val systemTrustAvailable: Boolean = false,
) : GatewayTlsTrustDecision
data class Failed(
val reason: GatewayTlsProbeFailure,
) : GatewayTlsTrustDecision
}
internal const val GATEWAY_TLS_PROBE_CONNECT_TIMEOUT_MS = 3_000
internal const val GATEWAY_TLS_PROBE_HANDSHAKE_TIMEOUT_MS = 10_000
private const val GATEWAY_TLS_FALLBACK_TIMEOUT_FLOOR_MS = 250
internal data class GatewayTlsProbeTimeouts(
val connectTimeoutMs: Int,
val handshakeTimeoutMs: Int,
)
internal fun splitGatewayTlsFallbackProbeTimeouts(
connectTimeoutMs: Int,
handshakeTimeoutMs: Int,
elapsedMs: Long,
): GatewayTlsProbeTimeouts? {
val totalBudgetMs = connectTimeoutMs.toLong() + handshakeTimeoutMs.toLong()
val remainingBudgetMs = (totalBudgetMs - elapsedMs).coerceIn(0, totalBudgetMs)
val minimumBudgetMs = GATEWAY_TLS_FALLBACK_TIMEOUT_FLOOR_MS.toLong() * 2
if (remainingBudgetMs < minimumBudgetMs) return null
val remainingMs = remainingBudgetMs.coerceAtMost(Int.MAX_VALUE.toLong()).toInt()
val proportionalConnectMs = ((remainingMs.toLong() * connectTimeoutMs) / totalBudgetMs).toInt()
val fallbackConnectMs =
proportionalConnectMs.coerceIn(
GATEWAY_TLS_FALLBACK_TIMEOUT_FLOOR_MS,
remainingMs - GATEWAY_TLS_FALLBACK_TIMEOUT_FLOOR_MS,
)
return GatewayTlsProbeTimeouts(
connectTimeoutMs = fallbackConnectMs,
handshakeTimeoutMs = remainingMs - fallbackConnectMs,
)
}
/** Public-DNS candidates may use Android's CA store and HTTPS hostname validation. */
internal fun isGatewayTlsSystemTrustCandidate(rawHost: String): Boolean = normalizedGatewayTlsDnsHost(rawHost) != null
/** Resolves probe evidence and any stored pin into one exhaustive trust decision. */
internal fun decideGatewayTlsTrust(
storedFingerprint: String?,
systemTrustCandidate: Boolean,
probeResult: GatewayTlsProbeResult,
): GatewayTlsTrustDecision {
val stored =
storedFingerprint
?.takeIf { it.isNotBlank() }
?.let(::normalizeGatewayTlsFingerprintInput)
?: if (storedFingerprint.isNullOrBlank()) {
null
} else {
return GatewayTlsTrustDecision.Failed(probeResult.failure ?: GatewayTlsProbeFailure.TLS_UNAVAILABLE)
}
val observed =
probeResult.fingerprintSha256?.let { raw ->
normalizeGatewayTlsFingerprintInput(raw)
?: return GatewayTlsTrustDecision.Failed(probeResult.failure ?: GatewayTlsProbeFailure.TLS_UNAVAILABLE)
}
if (stored == null && systemTrustCandidate && probeResult.systemTrusted) {
return GatewayTlsTrustDecision.SystemTrusted
}
if (observed != null) {
return if (stored == observed) {
GatewayTlsTrustDecision.PinnedTrust(observed)
} else {
GatewayTlsTrustDecision.PromptRequired(
fingerprintSha256 = observed,
previousFingerprintSha256 = stored,
systemTrustAvailable = stored != null && systemTrustCandidate && probeResult.systemTrusted,
)
}
}
if (stored != null) return GatewayTlsTrustDecision.PinnedTrust(stored)
return GatewayTlsTrustDecision.PromptRequired(
fingerprintSha256 = null,
previousFingerprintSha256 = null,
probeFailure = probeResult.failure,
)
}
/** Builds a TLS config that supports pinned fingerprints and trust-on-first-use. */
fun buildGatewayTlsConfig(
@@ -82,12 +178,13 @@ internal fun buildGatewayTlsConfig(
defaultTrust: X509TrustManager,
onStore: ((String) -> Unit)? = null,
): GatewayTlsConfig {
val expectedInput = params.expectedFingerprint?.takeIf { it.isNotBlank() }
val expected =
params.expectedFingerprint
expectedInput
?.let(::normalizeGatewayTlsFingerprint)
?.takeIf { it.isNotBlank() }
val effectiveFingerprint = AtomicReference(expected)
val usesPlatformTrust = expected == null && !params.allowTOFU
val usesPlatformTrust = expectedInput == null && !params.allowTOFU
fun recordAcceptedFingerprint(chain: Array<X509Certificate>) {
val certificate = chain.firstOrNull() ?: return
@@ -134,7 +231,10 @@ internal fun buildGatewayTlsConfig(
) {
if (chain.isEmpty()) throw CertificateException("empty certificate chain")
val fingerprint = sha256Hex(chain[0].encoded)
if (expected != null) {
if (expectedInput != null) {
if (expected == null) {
throw CertificateException("invalid gateway TLS fingerprint")
}
if (fingerprint != expected) {
throw CertificateException("gateway TLS fingerprint mismatch")
}
@@ -186,7 +286,7 @@ internal fun buildGatewayTlsConfig(
val context = SSLContext.getInstance("TLS")
context.init(null, arrayOf(trustManager), SecureRandom())
val verifier =
if (expected != null || params.allowTOFU) {
if (expectedInput != null || params.allowTOFU) {
// When pinning, we intentionally ignore hostname mismatch (service discovery often yields IPs).
HostnameVerifier { _, _ -> true }
} else {
@@ -200,7 +300,7 @@ internal fun buildGatewayTlsConfig(
)
}
/** Connects with a probe trust manager that captures the presented cert hash. */
/** Uses platform trust for public DNS, otherwise captures the presented cert hash. */
suspend fun probeGatewayTlsFingerprint(
host: String,
port: Int,
@@ -224,6 +324,32 @@ internal suspend fun probeGatewayTlsFingerprint(
if (connectTimeoutMs <= 0 || handshakeTimeoutMs <= 0) return GatewayTlsProbeResult(failure = GatewayTlsProbeFailure.ENDPOINT_UNREACHABLE)
return withContext(Dispatchers.IO) {
val probeDeadlineNanos =
System.nanoTime() +
(connectTimeoutMs.toLong() + handshakeTimeoutMs.toLong()) * 1_000_000L
var fallbackTimeouts = GatewayTlsProbeTimeouts(connectTimeoutMs, handshakeTimeoutMs)
if (isGatewayTlsSystemTrustCandidate(trimmedHost)) {
val fingerprintSha256 =
probeGatewayTlsSystemTrust(
host = trimmedHost,
port = port,
connectTimeoutMs = connectTimeoutMs,
handshakeTimeoutMs = handshakeTimeoutMs,
)
if (fingerprintSha256 != null) {
return@withContext GatewayTlsProbeResult(fingerprintSha256 = fingerprintSha256, systemTrusted = true)
}
// One probe budget total, not one budget for each trust attempt.
val totalBudgetMs = connectTimeoutMs.toLong() + handshakeTimeoutMs.toLong()
val remainingBudgetMs = ((probeDeadlineNanos - System.nanoTime()) / 1_000_000L).coerceAtLeast(0)
fallbackTimeouts =
splitGatewayTlsFallbackProbeTimeouts(
connectTimeoutMs = connectTimeoutMs,
handshakeTimeoutMs = handshakeTimeoutMs,
elapsedMs = totalBudgetMs - remainingBudgetMs,
) ?: return@withContext GatewayTlsProbeResult(failure = GatewayTlsProbeFailure.TLS_HANDSHAKE_TIMEOUT)
}
val fingerprintRef = AtomicReference<String?>(null)
val probeTrustManager =
@SuppressLint("CustomX509TrustManager")
@@ -279,8 +405,8 @@ internal suspend fun probeGatewayTlsFingerprint(
// TCP reachability and TLS handshake progress fail differently on mobile
// tailnets; keep the budgets separate so a reachable-but-slow secure
// endpoint does not collapse into generic gateway unreachable guidance.
socket.soTimeout = handshakeTimeoutMs
socket.connect(InetSocketAddress(trimmedHost, port), connectTimeoutMs)
socket.soTimeout = fallbackTimeouts.handshakeTimeoutMs
socket.connect(InetSocketAddress(trimmedHost, port), fallbackTimeouts.connectTimeoutMs)
connected = true
// Best-effort SNI for hostnames (avoid crashing on IP literals).
@@ -335,6 +461,33 @@ internal suspend fun probeGatewayTlsFingerprint(
}
}
private fun probeGatewayTlsSystemTrust(
host: String,
port: Int,
connectTimeoutMs: Int,
handshakeTimeoutMs: Int,
): String? {
val dnsHost = normalizedGatewayTlsDnsHost(host) ?: return null
val context = SSLContext.getInstance("TLS")
context.init(null, arrayOf(defaultTrustManager()), SecureRandom())
val socket = context.socketFactory.createSocket() as SSLSocket
return try {
socket.soTimeout = handshakeTimeoutMs
val parameters = socket.sslParameters
parameters.endpointIdentificationAlgorithm = "HTTPS"
parameters.serverNames = listOf(SNIHostName(dnsHost))
socket.sslParameters = parameters
socket.connect(InetSocketAddress(dnsHost, port), connectTimeoutMs)
socket.startHandshake()
val certificate = socket.session.peerCertificates.firstOrNull() as? X509Certificate ?: return null
sha256Hex(certificate.encoded)
} catch (_: Exception) {
null
} finally {
runCatching { socket.close() }
}
}
private fun defaultTrustManager(): X509TrustManager {
val factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
factory.init(null as java.security.KeyStore?)
@@ -352,11 +505,37 @@ private fun sha256Hex(data: ByteArray): String {
return out.toString()
}
/** Normalizes user-visible fingerprint text to lowercase bare SHA-256 hex. */
fun normalizeGatewayTlsFingerprint(raw: String): String {
/** Normalizes accepted fingerprint text to lowercase bare SHA-256 hex. */
fun normalizeGatewayTlsFingerprintInput(raw: String): String? {
val stripped =
raw
.trim()
.replace(Regex("^sha-?256\\s*:?\\s*", RegexOption.IGNORE_CASE), "")
return stripped.lowercase(Locale.US).filter { it in '0'..'9' || it in 'a'..'f' }
.replace(Regex("^sha-?256\\s*:\\s*", RegexOption.IGNORE_CASE), "")
val compact =
stripped
.filterNot { it == ':' || it.isWhitespace() }
.lowercase(Locale.US)
return compact.takeIf { value ->
value.length == 64 && value.all { it in '0'..'9' || it in 'a'..'f' }
}
}
/** Normalizes internal fingerprint text; invalid values become empty. */
fun normalizeGatewayTlsFingerprint(raw: String): String = normalizeGatewayTlsFingerprintInput(raw).orEmpty()
private fun normalizedGatewayTlsDnsHost(rawHost: String): String? {
val trimmed = rawHost.trim()
if (trimmed.startsWith('[') || trimmed.endsWith(']')) return null
val host = trimmed.trimEnd('.').lowercase(Locale.US)
if (host.isEmpty() || host.length > 253 || host.endsWith(".local")) return null
if (host.contains(':')) return null
val labels = host.split('.')
if (labels.size < 2 || labels.any { !isGatewayTlsDnsLabel(it) }) return null
if (labels.all { label -> label.all { it in '0'..'9' } }) return null
return host
}
private fun isGatewayTlsDnsLabel(label: String): Boolean {
if (label.isEmpty() || label.length > 63 || label.first() == '-' || label.last() == '-') return false
return label.all { it in 'a'..'z' || it in '0'..'9' || it == '-' }
}
@@ -1045,6 +1045,7 @@ internal val nativeStringResourceIds: Map<String, Int> =
"Runs" to R.string.native_848f54e89660cea4,
"Runs on-device while OpenClaw is visible." to R.string.native_83e2faed20a3cda4,
"Runtime" to R.string.native_1093115897879aa3,
"SHA-256 fingerprint" to R.string.native_684889f0079cc145,
"SMS" to R.string.native_40b601a10ca536c1,
"Save & Connect" to R.string.native_a2f29836cda5ceb1,
"Save Changes" to R.string.native_35322b5bb5a218a1,
@@ -1231,6 +1232,7 @@ internal val nativeStringResourceIds: Map<String, Int> =
"The connected OpenClaw agent can use device capabilities you enable. Continue only if you trust the Gateway and agent you connect to." to R.string.native_d20f43f925e706ce,
"The diary is waiting for its first entry." to R.string.native_5fc1927ca948f31c,
"The gateway can change this path but cannot clear an existing path." to R.string.native_23a91dbf4886c1f9,
"The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host." to R.string.native_385001409de8562a,
"The gateway session is coming back online. Agent shortcuts should settle automatically in a moment." to R.string.native_fa4f9ee12d15faec,
"The overview refreshes on reconnect and when this screen opens." to R.string.native_d9f641e1a02807cb,
"The result for \$slug is unknown. Reconnect, refresh Skills, then retry; the Gateway safely joins a matching install that is still running." to R.string.native_a6a20a23827b4cbd,
@@ -1251,6 +1253,7 @@ internal val nativeStringResourceIds: Map<String, Int> =
"This folder has no files yet." to R.string.native_027d7c7db6d8b3ef,
"This gateway connection needs operator.admin to install ClawHub skills." to R.string.native_f113b3bd283e216c,
"This gateway connection needs operator.admin to update skills." to R.string.native_6eddcceb82e4c01f,
"This gateway now presents a certificate trusted by this device." to R.string.native_430df68ec29a85a2,
"This gateway sign-in can list connected nodes, but it cannot approve new phone pairing. Pair new phones from a gateway admin session. Node capability approval is separate and still uses nodes approve <request id>." to R.string.native_adca3171c270301a,
"This image could not be decoded." to R.string.native_f2da2e47cd31a5dd,
"This is taking longer than expected.\nCheck that the Gateway is running and reachable." to R.string.native_af60a38d6b5866ce,
@@ -1319,6 +1322,7 @@ internal val nativeStringResourceIds: Map<String, Int> =
"Use a secure wss:// or Tailscale Serve Gateway, generate a full-access setup code in the Control UI or with openclaw qr, then scan or paste it below and reconnect to enable settings and upgrades." to R.string.native_57efc4ebe625cab5,
"Use only on a trusted private network." to R.string.native_24e1028cd7aef320,
"Use setup code" to R.string.native_57666930af1af35e,
"Use system trust" to R.string.native_f4e2076014711222,
"Use the Gateway computer's LAN address or secure remote hostname." to R.string.native_1291833ee42d8143,
"Use the recovery options below to reconnect." to R.string.native_e330f9d64f5ad4dd,
"Use the requestId from the pending command in the approve command." to R.string.native_f41d9e8b7e09aa24,
@@ -8,6 +8,7 @@ import ai.openclaw.app.R
import ai.openclaw.app.SensitiveFeatureConfig
import ai.openclaw.app.gateway.GatewayEndpoint
import ai.openclaw.app.gateway.isLocalCleartextGatewayHost
import ai.openclaw.app.gateway.normalizeGatewayTlsFingerprintInput
import ai.openclaw.app.hasPhotoReadPermission
import ai.openclaw.app.i18n.NativeText
import ai.openclaw.app.i18n.nativeString
@@ -106,6 +107,7 @@ import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
@@ -812,35 +814,77 @@ fun OnboardingFlow(
}
pendingTrust?.let { prompt ->
val manualEntry = prompt.fingerprintSha256 == null
val systemTrustAvailable = prompt.systemTrustAvailable
var manualFingerprint by
rememberSaveable(prompt.endpoint.stableId, prompt.probeFailure) {
mutableStateOf("")
}
val normalizedManualFingerprint = normalizeGatewayTlsFingerprintInput(manualFingerprint)
AlertDialog(
onDismissRequest = viewModel::declineGatewayTrustPrompt,
containerColor = ClawTheme.colors.surfaceRaised,
title = { Text(stringResource(R.string.trust_this_gateway), style = ClawTheme.type.section, color = ClawTheme.colors.text) },
text = {
val message =
if (prompt.previousFingerprintSha256.isNullOrBlank()) {
stringResource(R.string.gateway_trust_first_seen, prompt.fingerprintSha256)
} else {
stringResource(
R.string.gateway_trust_changed,
prompt.previousFingerprintSha256,
prompt.fingerprintSha256,
when {
manualEntry ->
nativeString(
"The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
)
prompt.previousFingerprintSha256.isNullOrBlank() ->
stringResource(R.string.gateway_trust_first_seen, prompt.fingerprintSha256)
else ->
stringResource(
R.string.gateway_trust_changed,
prompt.previousFingerprintSha256,
prompt.fingerprintSha256,
)
}
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
Text(
message,
style = ClawTheme.type.body,
color = ClawTheme.colors.textMuted,
)
if (systemTrustAvailable) {
Text(
nativeString("This gateway now presents a certificate trusted by this device."),
style = ClawTheme.type.body,
color = ClawTheme.colors.textMuted,
)
}
Text(
message,
style = ClawTheme.type.body,
color = ClawTheme.colors.textMuted,
)
if (manualEntry) {
OutlinedTextField(
value = manualFingerprint,
onValueChange = { manualFingerprint = it },
modifier = Modifier.fillMaxWidth(),
label = { Text(nativeString("SHA-256 fingerprint")) },
singleLine = true,
)
}
}
},
confirmButton = {
TextButton(onClick = viewModel::acceptGatewayTrustPrompt) {
TextButton(
onClick = {
viewModel.acceptGatewayTrustPrompt(if (manualEntry) normalizedManualFingerprint else null)
},
enabled = !manualEntry || normalizedManualFingerprint != null,
) {
Text(nativeString("Trust"))
}
},
dismissButton = {
TextButton(onClick = viewModel::declineGatewayTrustPrompt) {
Text(nativeString("Cancel"))
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
if (systemTrustAvailable) {
TextButton(onClick = viewModel::useSystemGatewayTrustPrompt) {
Text(nativeString("Use system trust"))
}
}
TextButton(onClick = viewModel::declineGatewayTrustPrompt) {
Text(nativeString("Cancel"))
}
}
},
)
@@ -17,6 +17,7 @@ import ai.openclaw.app.R
import ai.openclaw.app.chat.ChatSessionEntry
import ai.openclaw.app.currentAppLanguage
import ai.openclaw.app.firstGraphemeOrNull
import ai.openclaw.app.gateway.normalizeGatewayTlsFingerprintInput
import ai.openclaw.app.i18n.NativeText
import ai.openclaw.app.i18n.joinedNativeText
import ai.openclaw.app.i18n.nativeString
@@ -99,6 +100,7 @@ import androidx.compose.material.icons.outlined.Terminal
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
@@ -332,6 +334,7 @@ fun ShellScreen(
GatewayTrustDialog(
prompt = prompt,
onAccept = viewModel::acceptGatewayTrustPrompt,
onUseSystemTrust = viewModel::useSystemGatewayTrustPrompt,
onDecline = viewModel::declineGatewayTrustPrompt,
)
}
@@ -374,18 +377,31 @@ private fun CanvasOverlay(
@Composable
private fun GatewayTrustDialog(
prompt: NodeRuntime.GatewayTrustPrompt,
onAccept: () -> Unit,
onAccept: (String?) -> Unit,
onUseSystemTrust: () -> Unit,
onDecline: () -> Unit,
) {
val manualEntry = prompt.fingerprintSha256 == null
val systemTrustAvailable = prompt.systemTrustAvailable
var manualFingerprint by
rememberSaveable(prompt.endpoint.stableId, prompt.probeFailure) {
mutableStateOf("")
}
val normalizedManualFingerprint = normalizeGatewayTlsFingerprintInput(manualFingerprint)
val message =
if (prompt.previousFingerprintSha256.isNullOrBlank()) {
stringResource(R.string.gateway_trust_first_seen, prompt.fingerprintSha256)
} else {
stringResource(
R.string.gateway_trust_changed,
prompt.previousFingerprintSha256,
prompt.fingerprintSha256,
)
when {
manualEntry ->
nativeString(
"The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host.",
)
prompt.previousFingerprintSha256.isNullOrBlank() ->
stringResource(R.string.gateway_trust_first_seen, prompt.fingerprintSha256)
else ->
stringResource(
R.string.gateway_trust_changed,
prompt.previousFingerprintSha256,
prompt.fingerprintSha256,
)
}
AlertDialog(
@@ -398,15 +414,47 @@ private fun GatewayTrustDialog(
color = ClawTheme.colors.text,
)
},
text = { Text(message, style = ClawTheme.type.body, color = ClawTheme.colors.textMuted) },
text = {
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
Text(message, style = ClawTheme.type.body, color = ClawTheme.colors.textMuted)
if (systemTrustAvailable) {
Text(
nativeString("This gateway now presents a certificate trusted by this device."),
style = ClawTheme.type.body,
color = ClawTheme.colors.textMuted,
)
}
if (manualEntry) {
OutlinedTextField(
value = manualFingerprint,
onValueChange = { manualFingerprint = it },
modifier = Modifier.fillMaxWidth(),
label = { Text(nativeString("SHA-256 fingerprint")) },
singleLine = true,
)
}
}
},
confirmButton = {
TextButton(onClick = onAccept) {
TextButton(
onClick = {
onAccept(if (manualEntry) normalizedManualFingerprint else null)
},
enabled = !manualEntry || normalizedManualFingerprint != null,
) {
Text(stringResource(R.string.trust_and_continue))
}
},
dismissButton = {
TextButton(onClick = onDecline) {
Text(stringResource(R.string.cancel))
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
if (systemTrustAvailable) {
TextButton(onClick = onUseSystemTrust) {
Text(nativeString("Use system trust"))
}
}
TextButton(onClick = onDecline) {
Text(stringResource(R.string.cancel))
}
}
},
)
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"اللوحة"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"مزوّد واحد"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"تعذّرت قراءة شهادة Gateway تلقائيًا. الصق بصمة SHA-256 التي حصلت عليها من مضيف Gateway."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"فشل الإرسال: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"الجسر"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"خطأ في التسليم"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"في انتظار الموافقة على الجهاز"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"جارٍ تحميل سلسلة المحادثة"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"يقدّم Gateway هذا الآن شهادة موثوقة من هذا الجهاز."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"التداخل بالميلي ثانية"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"مستند"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"لصق الرمز المميز"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"لا يوجد موفرون"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"بصمة SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"لا توجد سلاسل محادثات بعد"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ميكروفون Bluetooth"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"الأخيرة"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"الحمولة · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"قيد التشغيل"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"إنهاء"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"استخدام ثقة النظام"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"لا يوجد مزوّدون جاهزون"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"يعطي الأولوية لميكروفونات Bluetooth المتصلة."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"تم حظر %1$s تطبيق من إعادة التوجيه."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Canvas"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 Anbieter"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Das Gateway-Zertifikat konnte nicht automatisch gelesen werden. Fügen Sie den auf dem Gateway-Host ermittelten SHA-256-Fingerabdruck ein."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Senden fehlgeschlagen: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bridge"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Zustellungsfehler"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Warten auf Gerätefreigabe"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Thread wird geladen"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dieses Gateway verwendet jetzt ein Zertifikat, dem dieses Gerät vertraut."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Staffelung in ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dokument"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Token einfügen"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Keine Anbieter"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"SHA-256-Fingerabdruck"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Noch keine Threads"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetooth-Mikrofon"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Zuletzt verwendet"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nutzdaten · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Wird ausgeführt"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Beenden"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Systemvertrauen verwenden"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Keine Anbieter bereit"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Priorisiert verbundene Bluetooth-Mikrofone."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s App ist für die Weiterleitung blockiert."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Lienzo"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 proveedor"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"No se pudo leer automáticamente el certificado del gateway. Pega la huella digital SHA-256 obtenida en el host del gateway."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Error al enviar: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Puente"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Error de entrega"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Esperando la aprobación del dispositivo"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Cargando hilo"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Este gateway ahora presenta un certificado en el que confía este dispositivo."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Escalonar ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"documento"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Pegar token"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"No hay proveedores"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Huella digital SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Aún no hay hilos"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Micrófono Bluetooth"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Reciente"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Carga útil · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"En ejecución"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Finalizar"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Usar la confianza del sistema"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"No hay proveedores listos"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Prioriza los micrófonos Bluetooth conectados."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s aplicación bloqueada para el reenvío."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"بوم"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"۱ ارائه‌دهنده"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"گواهی Gateway به‌طور خودکار قابل خواندن نبود. اثر انگشت SHA-256 دریافت‌شده در میزبان Gateway را جای‌گذاری کنید."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ارسال ناموفق بود: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"پل ارتباطی"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"خطای تحویل"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"در انتظار تأیید دستگاه"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"در حال بارگیری رشته"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"این Gateway اکنون گواهی‌ای ارائه می‌کند که مورد اعتماد این دستگاه است."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"میلی‌ثانیه پراکندگی"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"سند"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"چسباندن توکن"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ارائه‌دهنده‌ای وجود ندارد"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"اثر انگشت SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"هنوز رشته‌ای وجود ندارد"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"میکروفون Bluetooth"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"اخیر"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"بار داده · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"در حال اجرا"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"پایان"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"استفاده از اعتماد سیستم"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"هیچ ارائه‌دهنده آماده‌ای وجود ندارد"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"میکروفون‌های Bluetooth متصل را در اولویت قرار می‌دهد."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s برنامه از بازارسال مسدود شده است."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Canevas"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 fournisseur"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Le certificat du Gateway na pas pu être lu automatiquement. Collez lempreinte SHA-256 obtenue sur lhôte du Gateway."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Échec de lenvoi : %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Pont"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Erreur de livraison"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"En attente de lapprobation de lappareil"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Chargement du fil"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Ce Gateway présente désormais un certificat approuvé par cet appareil."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Décalage ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"document"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Coller le jeton"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Aucun fournisseur"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Empreinte SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Aucun fil pour le moment"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Microphone Bluetooth"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Récent"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Charge utile · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"En cours"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Terminer"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Utiliser la confiance du système"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Aucun fournisseur prêt"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Donne la priorité aux microphones Bluetooth connectés."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s application empêchée de transférer."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"कैनवास"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 प्रदाता"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gateway प्रमाणपत्र को स्वचालित रूप से पढ़ा नहीं जा सका। Gateway होस्ट पर प्राप्त SHA-256 फ़िंगरप्रिंट पेस्ट करें।"</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"भेजना विफल रहा: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ब्रिज"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"डिलीवरी त्रुटि"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"डिवाइस की स्वीकृति की प्रतीक्षा है"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"थ्रेड लोड हो रहा है"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"यह Gateway अब इस डिवाइस द्वारा विश्वसनीय प्रमाणपत्र प्रस्तुत करता है।"</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"विलंब ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"दस्तावेज़"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"टोकन पेस्ट करें"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"कोई प्रदाता नहीं"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"SHA-256 फ़िंगरप्रिंट"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"अभी तक कोई थ्रेड नहीं"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetooth माइक्रोफ़ोन"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"हाल के"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"पेलोड · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"चल रहा है"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"समाप्त करें"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"सिस्टम विश्वसनीयता का उपयोग करें"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"कोई तैयार प्रोवाइडर नहीं"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"कनेक्ट किए गए Bluetooth माइक्रोफ़ोन को प्राथमिकता देता है।"</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s ऐप को फ़ॉरवर्ड करने से ब्लॉक किया गया है।"</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Kanvas"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 penyedia"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sertifikat Gateway tidak dapat dibaca secara otomatis. Tempelkan sidik jari SHA-256 yang diperoleh di host Gateway."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gagal mengirim: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Jembatan"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Kesalahan Pengiriman"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Menunggu persetujuan perangkat"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Memuat utas"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gateway ini sekarang menyajikan sertifikat yang dipercaya oleh perangkat ini."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Jeda ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"dokumen"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Tempel token"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Tidak ada penyedia"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sidik jari SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Belum ada utas"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Mikrofon Bluetooth"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Terbaru"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Muatan · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Berjalan"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Akhiri"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gunakan kepercayaan sistem"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Tidak ada penyedia yang siap"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Memprioritaskan mikrofon Bluetooth yang terhubung."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s aplikasi diblokir agar tidak meneruskan."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Canvas"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 provider"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Non è stato possibile leggere automaticamente il certificato del Gateway. Incolla l\'impronta digitale SHA-256 ottenuta sull\'host del Gateway."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Invio non riuscito: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bridge"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Errore di consegna"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"In attesa dell\'approvazione del dispositivo"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Caricamento della conversazione"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Questo Gateway ora presenta un certificato considerato attendibile da questo dispositivo."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sfalsamento ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"documento"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Incolla token"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nessun provider"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Impronta digitale SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nessun thread"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Microfono Bluetooth"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Recenti"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Payload · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"In esecuzione"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Termina"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Usa l\'attendibilità di sistema"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nessun provider pronto"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dà priorità ai microfoni Bluetooth connessi."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s app bloccata dall\'inoltro."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"キャンバス"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"プロバイダー1件"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gateway証明書を自動的に読み取れませんでした。Gatewayホストで取得したSHA-256フィンガープリントを貼り付けてください。"</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"送信に失敗しました: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ブリッジ"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"配信エラー"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"デバイスの承認を待っています"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"スレッドを読み込み中"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"このGatewayは現在、このデバイスによって信頼されている証明書を提示しています。"</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ずらしミリ秒"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ドキュメント"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"トークンを貼り付け"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"プロバイダーがありません"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"SHA-256フィンガープリント"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"スレッドはまだありません"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetoothマイク"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"最近"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ペイロード · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"実行中"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"終了"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"システムの信頼設定を使用"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"準備完了のプロバイダーはありません"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"接続されているBluetoothマイクを優先します。"</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s 個のアプリの転送をブロックしました。"</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"캔버스"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"공급자 1개"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gateway 인증서를 자동으로 읽을 수 없습니다. Gateway 호스트에서 확인한 SHA-256 지문을 붙여넣으세요."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"전송 실패: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"브리지"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"전달 오류"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"기기 승인 대기 중"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"스레드 불러오는 중"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"이제 이 Gateway는 이 기기에서 신뢰하는 인증서를 제공합니다."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"지연 ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"문서"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"토큰 붙여넣기"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"제공자 없음"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"SHA-256 지문"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"아직 스레드가 없습니다"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetooth 마이크"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"최근"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"페이로드 · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"실행 중"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"종료"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"시스템 신뢰 사용"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"준비된 제공자 없음"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"연결된 Bluetooth 마이크를 우선 사용합니다."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s개 앱의 전달이 차단되었습니다."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Canvas"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 provider"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Het Gateway-certificaat kon niet automatisch worden gelezen. Plak de SHA-256-vingerafdruk die op de Gateway-host is verkregen."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Verzenden mislukt: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Brug"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bezorgfout"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Wachten op apparaatgoedkeuring"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Thread laden"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Deze Gateway gebruikt nu een certificaat dat door dit apparaat wordt vertrouwd."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Spreiding ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"document"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Token plakken"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Geen providers"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"SHA-256-vingerafdruk"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nog geen threads"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetooth-microfoon"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Recent"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Payload · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Actief"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Beëindigen"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Systeemvertrouwen gebruiken"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Geen providers gereed"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Geeft prioriteit aan verbonden Bluetooth-microfoons."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s app is geblokkeerd voor doorsturen."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Kanwa"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 dostawca"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nie udało się automatycznie odczytać certyfikatu Gateway. Wklej odcisk SHA-256 uzyskany na hoście Gateway."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Wysyłanie nie powiodło się: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Most"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Błąd dostarczenia"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Oczekiwanie na zatwierdzenie urządzenia"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Wczytywanie wątku"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Ten Gateway używa teraz certyfikatu zaufanego przez to urządzenie."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Rozłożenie ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"dokument"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Wklej token"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Brak dostawców"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Odcisk SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nie ma jeszcze żadnych wątków"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Mikrofon Bluetooth"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Ostatnie"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Ładunek · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Uruchomione"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Zakończ"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Użyj zaufania systemowego"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Brak gotowych dostawców"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nadaje priorytet podłączonym mikrofonom Bluetooth."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Zablokowano przekazywanie dla %1$s aplikacji."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Canvas"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 provedor"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Não foi possível ler automaticamente o certificado do Gateway. Cole a impressão digital SHA-256 obtida no host do Gateway."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Falha no envio: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Ponte"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Erro de entrega"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Aguardando aprovação do dispositivo"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Carregando conversa"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Este Gateway agora apresenta um certificado confiável para este dispositivo."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Escalonamento ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"documento"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Colar token"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nenhum provedor"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Impressão digital SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Ainda não há conversas"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Microfone Bluetooth"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Recentes"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Payload · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Em execução"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Encerrar"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Usar confiança do sistema"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nenhum provedor pronto"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Prioriza microfones Bluetooth conectados."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s app impedido de encaminhar."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Холст"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 провайдер"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Не удалось автоматически прочитать сертификат Gateway. Вставьте отпечаток SHA-256, полученный на хосте Gateway."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Не удалось отправить: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Мост"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Ошибка доставки"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Ожидание подтверждения устройства"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Загрузка ветки"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Теперь этот Gateway предоставляет сертификат, которому доверяет это устройство."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Интервал разброса, мс"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"документ"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Вставить токен"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Нет провайдеров"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Отпечаток SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Веток пока нет"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetooth-микрофон"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Недавние"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Полезная нагрузка · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Выполняется"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Завершить"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Использовать системное доверие"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Нет готовых провайдеров"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Приоритет отдается подключенным Bluetooth-микрофонам."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Переадресация заблокирована для %1$s приложения."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Arbetsyta"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 leverantör"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gateway-certifikatet kunde inte läsas automatiskt. Klistra in SHA-256-fingeravtrycket som hämtats på Gateway-värden."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Det gick inte att skicka: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Brygga"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Leveransfel"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Väntar på enhetsgodkännande"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Läser in tråd"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Denna Gateway använder nu ett certifikat som den här enheten litar på."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Förskjutning ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"dokument"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Klistra in token"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Inga leverantörer"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"SHA-256-fingeravtryck"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Inga trådar ännu"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetooth-mikrofon"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Senaste"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Nyttolast · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Körs"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Avsluta"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Använd systemets förtroende"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Inga leverantörer redo"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Prioriterar anslutna Bluetooth-mikrofoner."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s app blockerad från att vidarebefordra."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"แคนวาส"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ผู้ให้บริการ 1 ราย"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ไม่สามารถอ่านใบรับรองของ Gateway โดยอัตโนมัติได้ ให้วางลายนิ้วมือ SHA-256 ที่ได้รับจากโฮสต์ Gateway"</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ส่งไม่สำเร็จ: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"บริดจ์"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ข้อผิดพลาดในการส่ง"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"กำลังรอการอนุมัติอุปกรณ์"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"กำลังโหลดเธรด"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ขณะนี้ Gateway นี้แสดงใบรับรองที่อุปกรณ์นี้เชื่อถือ"</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"การหน่วงเหลื่อม ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"เอกสาร"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"วางโทเค็น"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ไม่มีผู้ให้บริการ"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ลายนิ้วมือ SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ยังไม่มีเธรด"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ไมโครโฟน Bluetooth"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ล่าสุด"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"เพย์โหลด · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"กำลังทำงาน"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"สิ้นสุด"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ใช้ความเชื่อถือของระบบ"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ไม่มีผู้ให้บริการที่พร้อมใช้งาน"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"ให้ความสำคัญกับไมโครโฟน Bluetooth ที่เชื่อมต่ออยู่"</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"บล็อกไม่ให้ส่งต่อ %1$s แอป"</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Tuval"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 sağlayıcı"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gateway sertifikası otomatik olarak okunamadı. Gateway ana bilgisayarından alınan SHA-256 parmak izini yapıştırın."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gönderilemedi: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Köprü"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Teslim Hatası"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Cihaz onayı bekleniyor"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"İleti dizisi yükleniyor"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bu Gateway artık bu cihazın güvendiği bir sertifika sunuyor."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Kaydırma ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"belge"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Token\'ı yapıştır"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sağlayıcı yok"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"SHA-256 parmak izi"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Henüz ileti dizisi yok"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetooth mikrofonu"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Son"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Veri yükü · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Çalışıyor"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bitir"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sistem güvenini kullan"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Hazır sağlayıcı yok"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bağlı Bluetooth mikrofonlarına öncelik verir."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s uygulamanın yönlendirmesi engellendi."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Полотно"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 провайдер"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Не вдалося автоматично прочитати сертифікат Gateway. Вставте відбиток SHA-256, отриманий на хості Gateway."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Не вдалося надіслати: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Міст"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Помилка доставки"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Очікування схвалення пристрою"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Завантаження гілки"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Тепер цей Gateway надає сертифікат, якому довіряє цей пристрій."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Зсув мс"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"документ"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Вставити токен"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Немає постачальників"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Відбиток SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Гілок ще немає"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetooth-мікрофон"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Нещодавні"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Корисне навантаження · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Виконується"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Завершити"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Використовувати системну довіру"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Немає готових провайдерів"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Надає пріоритет підключеним Bluetooth-мікрофонам."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Пересилання заблоковано для %1$s застосунку."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bảng vẽ"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 nhà cung cấp"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Không thể tự động đọc chứng chỉ của Gateway. Hãy dán dấu vân tay SHA-256 lấy được trên máy chủ Gateway."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gửi không thành công: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Cầu nối"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Lỗi gửi"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Đang chờ phê duyệt thiết bị"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Đang tải luồng"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gateway này hiện cung cấp chứng chỉ được thiết bị này tin cậy."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Độ lệch ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"tài liệu"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dán token"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Không có nhà cung cấp"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dấu vân tay SHA-256"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Chưa có luồng nào"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Micrô Bluetooth"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Gần đây"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Payload · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Đang chạy"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Kết thúc"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sử dụng độ tin cậy của hệ thống"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Không có nhà cung cấp nào sẵn sàng"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Ưu tiên micrô Bluetooth đã kết nối."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s ứng dụng bị chặn chuyển tiếp."</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"画布"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 个提供商"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"无法自动读取 Gateway 证书。请粘贴在 Gateway 主机上获取的 SHA-256 指纹。"</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"发送失败:%1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"桥接"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"投递错误"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"正在等待设备批准"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"正在加载对话"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"此 Gateway 现在提供的证书已受此设备信任。"</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"错开毫秒数"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"文档"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"粘贴令牌"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"无提供商"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"SHA-256 指纹"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"暂无对话"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"蓝牙麦克风"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"最近"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"负载 · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"运行中"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"结束"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"使用系统信任"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"没有就绪的提供方"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"优先使用已连接的蓝牙麦克风。"</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"已阻止 %1$s 个应用转发。"</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"畫布"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 個提供者"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"無法自動讀取 Gateway 憑證。請貼上從 Gateway 主機取得的 SHA-256 指紋。"</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"傳送失敗:%1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"橋接"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"傳送錯誤"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"正在等待裝置核准"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"正在載入對話串"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"此 Gateway 現在提供的憑證已受此裝置信任。"</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"錯開毫秒數"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"文件"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"貼上 token"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"沒有提供者"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"SHA-256 指紋"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"尚無對話串"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetooth 麥克風"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"最近"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"承載內容 · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"執行中"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"結束"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"使用系統信任設定"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"沒有已就緒的提供者"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"優先使用已連線的 Bluetooth 麥克風。"</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"已封鎖 %1$s 個應用程式進行轉送。"</string>
@@ -346,6 +346,7 @@
<string name="native_381428f5f251a764" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Conversation Send"</string>
<string name="native_3824a9f4dafe92c6" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Canvas"</string>
<string name="native_384ae4ab1a2830f9" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"1 provider"</string>
<string name="native_385001409de8562a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"The gateway certificate could not be read automatically. Paste the SHA-256 fingerprint obtained on the gateway host."</string>
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Send failed: %1$s"</string>
<string name="native_3892e10346fd2012" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bridge"</string>
<string name="native_38d198cd5303680f" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Delivery Error"</string>
@@ -403,6 +404,7 @@
<string name="native_429f6057535c1ea3" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Sub-agent"</string>
<string name="native_42e3a99c21767def" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Waiting for device approval"</string>
<string name="native_430798d3e8250938" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Loading thread"</string>
<string name="native_430df68ec29a85a2" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"This gateway now presents a certificate trusted by this device."</string>
<string name="native_43905968a540af6a" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Stagger ms"</string>
<string name="native_43988c156beabf7d" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"event create"</string>
<string name="native_43cc23fa52b87b4c" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"document"</string>
@@ -619,6 +621,7 @@
<string name="native_67b696468610b879" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Dashboard"</string>
<string name="native_67fa416afa64d304" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Paste token"</string>
<string name="native_6827238fea72c88b" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"No providers"</string>
<string name="native_684889f0079cc145" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"SHA-256 fingerprint"</string>
<string name="native_68944e10a8b4b9be" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"No threads yet"</string>
<string name="native_68a0cdfcc76d6ebd" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Bluetooth microphone"</string>
<string name="native_690dbe9dc0993c42" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Recent"</string>
@@ -1434,6 +1437,7 @@
<string name="native_f4cc820d308495c4" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Payload · %1$s"</string>
<string name="native_f4ccae29e1bb0c20" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Running"</string>
<string name="native_f4db1e48476f6075" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"End"</string>
<string name="native_f4e2076014711222" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Use system trust"</string>
<string name="native_f4ef7a41caa88dd1" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"No ready providers"</string>
<string name="native_f503d14f0c32a9c0" formatted="false" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Prioritizes connected Bluetooth microphones."</string>
<string name="native_f5171b47ebca6202" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"%1$s app blocked from forwarding."</string>
@@ -8,6 +8,7 @@ import ai.openclaw.app.gateway.GatewayErrorDetails
import ai.openclaw.app.gateway.GatewayRegistryEntry
import ai.openclaw.app.gateway.GatewayRegistryEntryKind
import ai.openclaw.app.gateway.GatewaySession
import ai.openclaw.app.gateway.GatewayTlsParams
import ai.openclaw.app.gateway.GatewayTlsProbeFailure
import ai.openclaw.app.gateway.GatewayTlsProbeResult
import ai.openclaw.app.node.ConnectionManager
@@ -430,7 +431,7 @@ class GatewayBootstrapAuthTest {
NodeRuntime(
app,
prefs,
tlsFingerprintProbe = { _, _ -> GatewayTlsProbeResult(fingerprintSha256 = "fp:1") },
tlsFingerprintProbe = { _, _ -> GatewayTlsProbeResult(fingerprintSha256 = "ab".repeat(32)) },
)
val explicitAuth =
NodeRuntime.GatewayConnectAuth(
@@ -445,7 +446,7 @@ class GatewayBootstrapAuthTest {
runtime.acceptGatewayTrustPrompt()
assertEquals("f1", prefs.loadGatewayTlsFingerprint(endpoint.stableId))
assertEquals("ab".repeat(32), prefs.loadGatewayTlsFingerprint(endpoint.stableId))
assertEquals("setup-bootstrap-token", waitForDesiredBootstrapToken(runtime, "nodeSession"))
assertNull(desiredBootstrapToken(runtime, "operatorSession"))
}
@@ -461,12 +462,14 @@ class GatewayBootstrapAuthTest {
)
val prefs = SecurePrefs(app, securePrefsOverride = securePrefs)
val endpoint = GatewayEndpoint.manual(host = "gateway.example", port = 18789)
prefs.saveGatewayTlsFingerprint(endpoint.stableId, "sha256:aa:aa:aa:aa")
val oldFingerprint = "aa".repeat(32)
val newFingerprint = "bb".repeat(32)
prefs.saveGatewayTlsFingerprint(endpoint.stableId, oldFingerprint)
val runtime =
NodeRuntime(
app,
prefs,
tlsFingerprintProbe = { _, _ -> GatewayTlsProbeResult(fingerprintSha256 = "sha256:bb:bb:bb:bb") },
tlsFingerprintProbe = { _, _ -> GatewayTlsProbeResult(fingerprintSha256 = newFingerprint, systemTrusted = true) },
)
runtime.connect(
@@ -475,13 +478,14 @@ class GatewayBootstrapAuthTest {
)
val prompt = waitForGatewayTrustPrompt(runtime)
assertEquals("aaaaaaaa", prompt.previousFingerprintSha256)
assertEquals("bbbbbbbb", prompt.fingerprintSha256)
assertEquals("sha256:aa:aa:aa:aa", prefs.loadGatewayTlsFingerprint(endpoint.stableId))
assertEquals(oldFingerprint, prompt.previousFingerprintSha256)
assertEquals(newFingerprint, prompt.fingerprintSha256)
assertTrue(prompt.systemTrustAvailable)
assertEquals(oldFingerprint, prefs.loadGatewayTlsFingerprint(endpoint.stableId))
runtime.declineGatewayTrustPrompt()
assertEquals("sha256:aa:aa:aa:aa", prefs.loadGatewayTlsFingerprint(endpoint.stableId))
assertEquals(oldFingerprint, prefs.loadGatewayTlsFingerprint(endpoint.stableId))
runtime.connect(
endpoint,
@@ -490,9 +494,76 @@ class GatewayBootstrapAuthTest {
waitForGatewayTrustPrompt(runtime)
runtime.acceptGatewayTrustPrompt()
assertEquals("bbbbbbbb", prefs.loadGatewayTlsFingerprint(endpoint.stableId))
assertEquals(newFingerprint, prefs.loadGatewayTlsFingerprint(endpoint.stableId))
}
@Test
fun connect_systemTrustedCandidateWithoutStoredPinUsesPlatformTrust() {
val app = RuntimeEnvironment.getApplication()
val securePrefs =
app.getSharedPreferences(
"openclaw.node.secure.test.${UUID.randomUUID()}",
android.content.Context.MODE_PRIVATE,
)
val prefs = SecurePrefs(app, securePrefsOverride = securePrefs)
val endpoint = GatewayEndpoint.manual(host = "gateway.example", port = 18789)
val runtime =
NodeRuntime(
app,
prefs,
tlsFingerprintProbe = { _, _ -> GatewayTlsProbeResult(fingerprintSha256 = "bb".repeat(32), systemTrusted = true) },
)
runtime.connect(
endpoint,
NodeRuntime.GatewayConnectAuth(token = "test-token-placeholder", bootstrapToken = null, password = null),
)
val desired = waitForDesiredConnection(runtime, "nodeSession")
val tls = readField<GatewayTlsParams>(desired, "tls")
assertNull(tls.expectedFingerprint)
assertNull(prefs.loadGatewayTlsFingerprint(endpoint.stableId))
assertEquals(endpoint.stableId, prefs.gatewayRegistry.activeStableId.value)
assertNull(runtime.pendingGatewayTrust.value)
}
@Test
fun connect_systemTrustedChangedPinSwitchClearsPinAndUsesPlatformTrust() {
val app = RuntimeEnvironment.getApplication()
val securePrefs =
app.getSharedPreferences(
"openclaw.node.secure.test.${UUID.randomUUID()}",
android.content.Context.MODE_PRIVATE,
)
val prefs = SecurePrefs(app, securePrefsOverride = securePrefs)
val endpoint = GatewayEndpoint.manual(host = "gateway.example", port = 18789)
val oldFingerprint = "aa".repeat(32)
val newFingerprint = "bb".repeat(32)
prefs.saveGatewayTlsFingerprint(endpoint.stableId, oldFingerprint)
val runtime =
NodeRuntime(
app,
prefs,
tlsFingerprintProbe = { _, _ -> GatewayTlsProbeResult(fingerprintSha256 = newFingerprint, systemTrusted = true) },
)
runtime.connect(
endpoint,
NodeRuntime.GatewayConnectAuth(token = "test-token-placeholder", bootstrapToken = null, password = null),
)
val prompt = waitForGatewayTrustPrompt(runtime)
assertTrue(prompt.systemTrustAvailable)
assertEquals(oldFingerprint, prefs.loadGatewayTlsFingerprint(endpoint.stableId))
runtime.useSystemGatewayTrustPrompt()
val desired = waitForDesiredConnection(runtime, "nodeSession")
val tls = readField<GatewayTlsParams>(desired, "tls")
assertNull(tls.expectedFingerprint)
assertNull(prefs.loadGatewayTlsFingerprint(endpoint.stableId))
}
@Test
fun connect_ignoresStaleTlsProbeAfterDisconnect() =
runBlocking {
@@ -504,7 +575,8 @@ class GatewayBootstrapAuthTest {
)
val prefs = SecurePrefs(app, securePrefsOverride = securePrefs)
val endpoint = GatewayEndpoint.manual(host = "gateway.example", port = 18789)
prefs.saveGatewayTlsFingerprint(endpoint.stableId, "aaaaaaaa")
val fingerprint = "aa".repeat(32)
prefs.saveGatewayTlsFingerprint(endpoint.stableId, fingerprint)
val probeStarted = CompletableDeferred<Unit>()
val probeResult = CompletableDeferred<GatewayTlsProbeResult>()
val runtime =
@@ -535,13 +607,13 @@ class GatewayBootstrapAuthTest {
?: error("Expected one TLS probe job")
runtime.disconnect()
probeResult.complete(GatewayTlsProbeResult(fingerprintSha256 = "aaaaaaaa"))
probeResult.complete(GatewayTlsProbeResult(fingerprintSha256 = fingerprint))
// Join the owning coroutine so assertions run after its stale-attempt guard.
probeJob.join()
assertNull(runtime.pendingGatewayTrust.value)
assertNull(desiredBootstrapToken(runtime, "nodeSession"))
assertEquals("aaaaaaaa", prefs.loadGatewayTlsFingerprint(endpoint.stableId))
assertEquals(fingerprint, prefs.loadGatewayTlsFingerprint(endpoint.stableId))
}
@Test
@@ -580,7 +652,7 @@ class GatewayBootstrapAuthTest {
runtime.connect(endpoint)
probeStarted.await()
assertTrue(runtime.forgetGateway(endpoint.stableId))
probeResult.complete(GatewayTlsProbeResult(fingerprintSha256 = "aaaaaaaa"))
probeResult.complete(GatewayTlsProbeResult(fingerprintSha256 = "aa".repeat(32)))
yield()
assertNull(
@@ -685,7 +757,39 @@ class GatewayBootstrapAuthTest {
"Failed: no secure gateway endpoint was detected. Enable gateway TLS or Tailscale Serve, or use a trusted private LAN address with Unencrypted selected.",
waitForStatusText(runtime),
)
assertNull(runtime.pendingGatewayTrust.value)
val prompt = waitForGatewayTrustPrompt(runtime)
assertNull(prompt.fingerprintSha256)
assertEquals(GatewayTlsProbeFailure.TLS_UNAVAILABLE, prompt.probeFailure)
}
@Test
fun connect_enforcesAcceptedManualFingerprintAfterTlsProbeFailure() {
val app = RuntimeEnvironment.getApplication()
val prefs =
SecurePrefs(
app,
app.getSharedPreferences("openclaw.node.secure.test.${UUID.randomUUID()}", android.content.Context.MODE_PRIVATE),
)
val runtime =
NodeRuntime(
app,
prefs,
tlsFingerprintProbe = { _, _ -> GatewayTlsProbeResult(failure = GatewayTlsProbeFailure.TLS_UNAVAILABLE) },
)
val endpoint = GatewayEndpoint.manual(host = "gateway.example", port = 18789)
runtime.connect(
endpoint,
NodeRuntime.GatewayConnectAuth(token = "test-token-placeholder", bootstrapToken = null, password = null),
)
waitForGatewayTrustPrompt(runtime)
val manualFingerprint = "cd".repeat(32)
runtime.acceptGatewayTrustPrompt("SHA256: ${manualFingerprint.uppercase()}")
val desired = waitForDesiredConnection(runtime, "nodeSession")
val tls = readField<GatewayTlsParams>(desired, "tls")
assertEquals(manualFingerprint, tls.expectedFingerprint)
assertEquals(manualFingerprint, prefs.loadGatewayTlsFingerprint(endpoint.stableId))
}
@Test
@@ -712,7 +816,9 @@ class GatewayBootstrapAuthTest {
"Failed: secure endpoint reached, but TLS fingerprint verification timed out. Check Tailscale Serve or gateway TLS and retry.",
waitForStatusText(runtime),
)
assertNull(runtime.pendingGatewayTrust.value)
val prompt = waitForGatewayTrustPrompt(runtime)
assertNull(prompt.fingerprintSha256)
assertEquals(GatewayTlsProbeFailure.TLS_HANDSHAKE_TIMEOUT, prompt.probeFailure)
}
@Test
@@ -68,7 +68,7 @@ class GatewaySessionCustomHeadersTest {
val prefs = SecurePrefs(app, securePrefsOverride = securePrefsBacking)
val stableId = "manual|gateway.example|443"
val endpoint = GatewayEndpoint.manual(host = "gateway.example", port = 443)
val tls = GatewayTlsParams(required = true, expectedFingerprint = "aa", allowTOFU = false, stableId = stableId)
val tls = GatewayTlsParams(required = true, expectedFingerprint = "aa".repeat(32), allowTOFU = false, stableId = stableId)
prefs.saveGatewayCustomHeaders(stableId, mapOf("CF-Access-Client-Id" to "client-id"))
securePrefsBacking
@@ -2,6 +2,9 @@ package ai.openclaw.app.gateway
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
import java.net.InetAddress
import java.net.ServerSocket
@@ -14,6 +17,123 @@ import javax.net.ssl.X509ExtendedTrustManager
import kotlin.concurrent.thread
class GatewayTlsTest {
@Test
fun splitGatewayTlsFallbackProbeTimeouts_skipsFallbackAfterBudgetExpires() {
assertNull(
splitGatewayTlsFallbackProbeTimeouts(
connectTimeoutMs = 3_000,
handshakeTimeoutMs = 10_000,
elapsedMs = 13_001,
),
)
}
@Test
fun splitGatewayTlsFallbackProbeTimeouts_preservesNearFullBudgetAfterFastFailure() {
val timeouts =
splitGatewayTlsFallbackProbeTimeouts(
connectTimeoutMs = 3_000,
handshakeTimeoutMs = 10_000,
elapsedMs = 50,
) ?: error("expected fallback timeouts")
assertEquals(2_988, timeouts.connectTimeoutMs)
assertEquals(9_962, timeouts.handshakeTimeoutMs)
assertEquals(12_950, timeouts.connectTimeoutMs + timeouts.handshakeTimeoutMs)
}
@Test
fun normalizeGatewayTlsFingerprintInput_acceptsPrefixColonsWhitespaceAndCase() {
val expected = "ab".repeat(32)
val colonSeparated = expected.uppercase().chunked(2).joinToString(":")
assertEquals(expected, normalizeGatewayTlsFingerprintInput(" SHA256: $colonSeparated\n"))
assertEquals(expected, normalizeGatewayTlsFingerprintInput("sha-256:\t${expected.uppercase()}"))
assertEquals(expected, normalizeGatewayTlsFingerprintInput(expected))
}
@Test
fun normalizeGatewayTlsFingerprintInput_rejectsWrongLengthAndGarbage() {
assertNull(normalizeGatewayTlsFingerprintInput("ab".repeat(31)))
assertNull(normalizeGatewayTlsFingerprintInput("ab".repeat(32) + "00"))
assertNull(normalizeGatewayTlsFingerprintInput("sha256: ${"ab".repeat(31)}:gg"))
assertNull(normalizeGatewayTlsFingerprintInput("not-a-fingerprint"))
}
@Test
fun isGatewayTlsSystemTrustCandidate_classifiesPublicDnsOnly() {
assertFalse(isGatewayTlsSystemTrustCandidate("gateway.local"))
assertFalse(isGatewayTlsSystemTrustCandidate("gateway.local."))
assertFalse(isGatewayTlsSystemTrustCandidate("192.0.2.10"))
assertFalse(isGatewayTlsSystemTrustCandidate("127.1"))
assertFalse(isGatewayTlsSystemTrustCandidate("[2001:db8::10]"))
assertFalse(isGatewayTlsSystemTrustCandidate("2001:db8::10"))
assertFalse(isGatewayTlsSystemTrustCandidate("[gateway.example.com]"))
assertFalse(isGatewayTlsSystemTrustCandidate("gateway"))
assertTrue(isGatewayTlsSystemTrustCandidate("gateway.example.com"))
assertTrue(isGatewayTlsSystemTrustCandidate("node.tailnet-name.ts.net"))
}
@Test
fun decideGatewayTlsTrust_coversStoredPinSystemTrustCandidateMatrix() {
val stored = "aa".repeat(32)
val observed = "bb".repeat(32)
for (hasStoredPin in listOf(false, true)) {
for (systemTrusted in listOf(false, true)) {
for (candidate in listOf(false, true)) {
val decision =
decideGatewayTlsTrust(
storedFingerprint = stored.takeIf { hasStoredPin },
systemTrustCandidate = candidate,
probeResult = GatewayTlsProbeResult(fingerprintSha256 = observed, systemTrusted = systemTrusted),
)
if (!hasStoredPin && systemTrusted && candidate) {
assertEquals(GatewayTlsTrustDecision.SystemTrusted, decision)
} else {
val prompt = decision as GatewayTlsTrustDecision.PromptRequired
assertEquals(observed, prompt.fingerprintSha256)
assertEquals(stored.takeIf { hasStoredPin }, prompt.previousFingerprintSha256)
assertEquals(hasStoredPin && systemTrusted && candidate, prompt.systemTrustAvailable)
}
}
}
}
}
@Test
fun decideGatewayTlsTrust_keepsPinWhenSystemTrustDoesNotReplaceIt() {
val stored = "aa".repeat(32)
assertEquals(
GatewayTlsTrustDecision.PinnedTrust(stored),
decideGatewayTlsTrust(
storedFingerprint = stored,
systemTrustCandidate = true,
probeResult = GatewayTlsProbeResult(fingerprintSha256 = stored, systemTrusted = true),
),
)
assertEquals(
GatewayTlsTrustDecision.PinnedTrust(stored),
decideGatewayTlsTrust(
storedFingerprint = stored,
systemTrustCandidate = true,
probeResult = GatewayTlsProbeResult(failure = GatewayTlsProbeFailure.TLS_UNAVAILABLE),
),
)
assertEquals(
GatewayTlsTrustDecision.PromptRequired(
fingerprintSha256 = null,
previousFingerprintSha256 = null,
probeFailure = GatewayTlsProbeFailure.TLS_UNAVAILABLE,
),
decideGatewayTlsTrust(
storedFingerprint = null,
systemTrustCandidate = true,
probeResult = GatewayTlsProbeResult(failure = GatewayTlsProbeFailure.TLS_UNAVAILABLE),
),
)
}
@Test
fun buildGatewayTlsConfig_exposesNormalizedExpectedRouteFingerprint() {
val expected = "ab".repeat(32)
@@ -62,6 +182,37 @@ class GatewayTlsTest {
assertEquals(0, defaultTrust.serverTwoArgumentCalls)
}
@Test
fun buildGatewayTlsConfig_rejectsInvalidStoredFingerprintInsteadOfUsingPlatformTrust() {
val defaultTrust = RecordingExtendedTrustManager()
val config =
buildGatewayTlsConfig(
params =
GatewayTlsParams(
required = true,
expectedFingerprint = "not-a-sha256-fingerprint",
allowTOFU = false,
stableId = "gateway-1",
),
defaultTrust = defaultTrust,
)
val failure =
runCatching {
Socket().use { socket ->
(config.trustManager as X509ExtendedTrustManager).checkServerTrusted(
emptyArray(),
"RSA",
socket,
)
}
}.exceptionOrNull()
assertTrue(failure is java.security.cert.CertificateException)
assertEquals(0, defaultTrust.serverSocketCalls)
assertEquals(0, defaultTrust.serverTwoArgumentCalls)
}
@Test
fun probeGatewayTlsFingerprint_reportsHandshakeTimeoutAfterTcpConnect() =
runBlocking {