mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 02:06:43 +00:00
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:
+479
-415
File diff suppressed because it is too large
Load Diff
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 l’appareil 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 n’a pas pu être lu automatiquement. Collez l’empreinte SHA-256 obtenue sur l’hô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 n’a pas pu être lu automatiquement. Collez l’empreinte SHA-256 obtenue sur l’hô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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 n’a pas pu être lu automatiquement. Collez l’empreinte SHA-256 obtenue sur l’hôte du Gateway."</string>
|
||||
<string name="native_387b2569e440838c" tools:ignore="Typos,TypographyDashes,TypographyEllipsis">"Échec de l’envoi : %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 l’approbation de l’appareil"</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
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user