From 1c3084eef465676c1b1fd733cefad72edb376d56 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 10:27:12 +0100 Subject: [PATCH 1/6] Autosync the updated translations (#13960) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/pl/messages.json | 18 +++++++++--------- apps/desktop/src/locales/zh_CN/messages.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index f78313c7fd6..ef8cdc6eb9b 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -907,7 +907,7 @@ "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "verifyYourIdentity": { - "message": "Verify your Identity" + "message": "Potwierdź swoją tożsamość" }, "weDontRecognizeThisDevice": { "message": "Nie rozpoznajemy tego urządzenia. Wpisz kod wysłany na Twój e-mail, aby zweryfikować tożsamość." @@ -998,7 +998,7 @@ "message": "Nie" }, "location": { - "message": "Location" + "message": "Lokalizacja" }, "overwritePassword": { "message": "Zastąp hasło" @@ -3488,22 +3488,22 @@ "message": "Warning: Agent Forwarding" }, "agentForwardingWarningText": { - "message": "This request comes from a remote device that you are logged into" + "message": "To żądanie pochodzi ze zdalnego urządzenia, do którego jesteś zalogowany" }, "sshkeyApprovalMessageInfix": { "message": "wnioskuje o dostęp do" }, "sshkeyApprovalMessageSuffix": { - "message": "in order to" + "message": "w celu" }, "sshActionLogin": { - "message": "authenticate to a server" + "message": "autoryzacji na serwerze" }, "sshActionSign": { - "message": "sign a message" + "message": "podpisania wiadomości" }, "sshActionGitSign": { - "message": "sign a git commit" + "message": "podpisania commita w giciem" }, "unknownApplication": { "message": "Aplikacja" @@ -3518,7 +3518,7 @@ "message": "Importuj klucz ze schowka" }, "sshKeyImported": { - "message": "SSH key imported successfully" + "message": "Klucz SSH zaimportowano pomyślnie" }, "fileSavedToDevice": { "message": "Plik zapisany na urządzeniu. Zarządzaj plikiem na swoim urządzeniu." @@ -3578,6 +3578,6 @@ "message": "Rozszerzenie przeglądarki, którego używasz, jest nieaktualne. Zaktualizuj je lub wyłącz weryfikację odcisku palca integracji przeglądarki w ustawieniach aplikacji desktopowej." }, "changeAtRiskPassword": { - "message": "Change at-risk password" + "message": "Zmień zagrożone hasło" } } diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index 8bf4d16c474..6a12138b48f 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -2470,7 +2470,7 @@ "message": "切换账户" }, "alreadyHaveAccount": { - "message": "已经拥有账户了吗?" + "message": "已经有账户了吗?" }, "options": { "message": "选项" From 714a3f33e40563ebc5734a10f9af0a3ba5d1cdb1 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 10:28:16 +0100 Subject: [PATCH 2/6] Autosync the updated translations (#13961) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/id/messages.json | 64 +++++++++---------- apps/browser/src/_locales/nl/messages.json | 36 +++++------ apps/browser/src/_locales/zh_CN/messages.json | 6 +- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index 33f44c60579..0146fb2a000 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -186,7 +186,7 @@ "message": "Salin catatan" }, "copy": { - "message": "Copy", + "message": "Salin", "description": "Copy to clipboard" }, "fill": { @@ -380,7 +380,7 @@ "message": "Sunting Folder" }, "editFolderWithName": { - "message": "Edit folder: $FOLDERNAME$", + "message": "Sunting folder: $FOLDERNAME$", "placeholders": { "foldername": { "content": "$1", @@ -462,16 +462,16 @@ "message": "Buat frasa sandi" }, "passwordGenerated": { - "message": "Password generated" + "message": "Kata sandi dibuat" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Frasa sandi dibuat" }, "usernameGenerated": { - "message": "Username generated" + "message": "Nama pengguna dibuat" }, "emailGenerated": { - "message": "Email generated" + "message": "Surel dibuat" }, "regeneratePassword": { "message": "Buat Ulang Kata Sandi" @@ -653,7 +653,7 @@ "message": "Peramban Anda tidak mendukung menyalin clipboard dengan mudah. Salin secara manual." }, "verifyYourIdentity": { - "message": "Verify your identity" + "message": "Verifikasikan identitas Anda" }, "weDontRecognizeThisDevice": { "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." @@ -905,7 +905,7 @@ "message": "Tidak" }, "location": { - "message": "Location" + "message": "Lokasi" }, "unexpectedError": { "message": "Terjadi kesalahan yang tak diduga." @@ -2461,7 +2461,7 @@ "message": "Change this in settings" }, "change": { - "message": "Change" + "message": "Ubah" }, "changeButtonTitle": { "message": "Change password - $ITEMNAME$", @@ -4784,7 +4784,7 @@ "message": "Text Sends" }, "accountActions": { - "message": "Account actions" + "message": "Tindakan akun" }, "showNumberOfAutofillSuggestions": { "message": "Show number of login autofill suggestions on extension icon" @@ -4793,22 +4793,22 @@ "message": "Show quick copy actions on Vault" }, "systemDefault": { - "message": "System default" + "message": "Baku sistem" }, "enterprisePolicyRequirementsApplied": { - "message": "Enterprise policy requirements have been applied to this setting" + "message": "Persyaratan kebijakan perusahaan telah diterapkan ke pengaturan ini" }, "sshPrivateKey": { - "message": "Private key" + "message": "Kunci privat" }, "sshPublicKey": { - "message": "Public key" + "message": "Kunci publik" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Sidik jari" }, "sshKeyAlgorithm": { - "message": "Key type" + "message": "Tipe kunci" }, "sshKeyAlgorithmED25519": { "message": "ED25519" @@ -4823,7 +4823,7 @@ "message": "RSA 4096-Bit" }, "retry": { - "message": "Retry" + "message": "Coba lagi" }, "vaultCustomTimeoutMinimum": { "message": "Minimum custom timeout is 1 minute." @@ -5075,16 +5075,16 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Tidak" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Ya, saya dapat mengakses surel saya secara handla" }, "turnOnTwoStepLogin": { "message": "Turn on two-step login" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Ubah surel akun" }, "extensionWidth": { "message": "Lebar ekstensi" @@ -5096,31 +5096,31 @@ "message": "Ekstra lebar" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "Kata sandi yang Anda masukkan tidak benar." }, "importSshKey": { - "message": "Import" + "message": "Impor" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Konfirmasi kata sandi" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "Masukkan kata sandi untuk kunci SSH." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "Masukkan kata sandi" }, "invalidSshKey": { - "message": "The SSH key is invalid" + "message": "Kunci SSH tidak valid" }, "sshKeyTypeUnsupported": { - "message": "The SSH key type is not supported" + "message": "Tipe kunci SSH tidak didukung" }, "importSshKeyFromClipboard": { - "message": "Import key from clipboard" + "message": "Impor kunci dari papan klip" }, "sshKeyImported": { - "message": "SSH key imported successfully" + "message": "Kunci SSH sukses diimpor" }, "cannotRemoveViewOnlyCollections": { "message": "Anda tidak dapat menghapus koleksi dengan izin hanya lihat: $COLLECTIONS$", @@ -5132,12 +5132,12 @@ } }, "updateDesktopAppOrDisableFingerprintDialogTitle": { - "message": "Please update your desktop application" + "message": "Harap perbarui aplikasi desktop Anda" }, "updateDesktopAppOrDisableFingerprintDialogMessage": { - "message": "To use biometric unlock, please update your desktop application, or disable fingerprint unlock in the desktop settings." + "message": "Untuk memakai pembuka kunci biometrik, harap perbarui aplikasi desktop Anda, atau matikan buka kunci sidik jari dalam pengaturan desktop." }, "changeAtRiskPassword": { - "message": "Change at-risk password" + "message": "Ubah kata sandi yang berrisiko" } } diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 65d8d6f740f..1c2b09ca3e3 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -81,7 +81,7 @@ "message": "Hoofdwachtwoordhint (optioneel)" }, "passwordStrengthScore": { - "message": "Score wachtwoordsterkte $SCORE$", + "message": "Wachtwoordsterkte score $SCORE$", "placeholders": { "score": { "content": "$1", @@ -878,10 +878,10 @@ "message": "Druk op je YubiKey om te verifiëren" }, "duoTwoFactorRequiredPageSubtitle": { - "message": "Jouw account vereist Duo-tweestapsaanmelding. Volg de onderstaande stappen om het inloggen te voltooien." + "message": "Jouw account vereist Duo tweestapslogin. Volg de onderstaande stappen om het inloggen te voltooien." }, "followTheStepsBelowToFinishLoggingIn": { - "message": "Volg de onderstaande stappen om in te loggen." + "message": "Volg de onderstaande stappen om het inloggen af te ronden." }, "restartRegistration": { "message": "Registratie herstarten" @@ -1040,7 +1040,7 @@ "message": "Klik op items om automatisch in te vullen op de kluisweergave" }, "clickToAutofill": { - "message": "Klik op gesuggereerde items om deze automatisch invullen" + "message": "Klik items in de automatisch invullen suggestie om in te vullen" }, "clearClipboard": { "message": "Klembord wissen", @@ -1075,7 +1075,7 @@ "description": "Shown to user after login is updated." }, "saveAsNewLoginAction": { - "message": "Als nieuwe login opslaan", + "message": "Opslaan als nieuwe login", "description": "Button text for saving login details as a new entry." }, "updateLoginAction": { @@ -1422,7 +1422,7 @@ "message": "Mijn gegevens onthouden" }, "dontAskAgainOnThisDeviceFor30Days": { - "message": "30 dagen niet meer vragen op dit apparaat" + "message": "30 dagen niet opnieuw vragen op dit apparaat" }, "sendVerificationCodeEmailAgain": { "message": "E-mail met verificatiecode opnieuw versturen" @@ -1459,7 +1459,7 @@ "message": "Beveiligingssleutel lezen" }, "awaitingSecurityKeyInteraction": { - "message": "Wacht op interactie met beveiligingssleutel..." + "message": "Wacht op interactie met beveiligingssleutel…" }, "loginUnavailable": { "message": "Login niet beschikbaar" @@ -1474,7 +1474,7 @@ "message": "Opties voor tweestapsaanmelding" }, "selectTwoStepLoginMethod": { - "message": "Kies methode voor tweestapsaanmelding" + "message": "Kies methode voor tweestapslogin" }, "recoveryCodeDesc": { "message": "Ben je de toegang tot al je tweestapsaanbieders verloren? Gebruik dan je herstelcode om alle tweestapsaanbieders op je account uit te schakelen." @@ -2164,7 +2164,7 @@ "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultCustomization": { - "message": "Kluis-aanpassingen" + "message": "Kluis aanpassingen" }, "vaultTimeoutAction": { "message": "Actie bij time-out" @@ -2176,10 +2176,10 @@ "message": "Nieuwe aanpassingsopties" }, "newCustomizationOptionsCalloutContent": { - "message": "Personaliseer je kluiservaring met snelle kopieeracties, compacte modus en meer!" + "message": "Pas je kluis ervaring aan met snelle kopieeracties, compacte modus en meer!" }, "newCustomizationOptionsCalloutLink": { - "message": "Alle personalisatie-instellingen bekijken" + "message": "Alle weergave-instellingen bekijken" }, "lock": { "message": "Vergrendelen", @@ -2498,7 +2498,7 @@ } }, "atRiskPasswordsDescMultiOrgPlural": { - "message": "Je organisatie(s) vragen je de $COUNT$ wachtwoorden te wijzigen omdat ze een risico vormen.", + "message": "Je organisaties vragen je de $COUNT$ wachtwoorden te wijzigen omdat ze een risico vormen.", "placeholders": { "count": { "content": "$1", @@ -2531,14 +2531,14 @@ "message": "Risicovolle wachtwoorden bekijken" }, "reviewAtRiskLoginsSlideDesc": { - "message": "De wachtwoorden van je organisatie zijn in gevaar omdat ze zwak, hergebruikt en/of blootgelegd zijn.", + "message": "De wachtwoorden van je organisatie zijn in gevaar omdat ze zwak, hergebruikt en/of gelekt zijn.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, "reviewAtRiskLoginSlideImgAlt": { "message": "Voorbeeld van een lijst van risicovolle logins" }, "generatePasswordSlideDesc": { - "message": "Genereer snel een sterk, uniek wachtwoord met het automatisch invulmenu van Bitwaren op de risicovolle website.", + "message": "Genereer snel een sterk, uniek wachtwoord met het automatisch invulmenu van Bitwarden op de risicovolle website.", "description": "Description of the generate password slide on the at-risk password page carousel" }, "generatePasswordSlideImgAlt": { @@ -2552,7 +2552,7 @@ "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, "updateInBitwardenSlideImgAlt": { - "message": "Voorbeeld van een Bitwarden-melding die de gebruiker aanspoort tot het bijwerken van de login" + "message": "Voorbeeld van een Bitwarden melding die de gebruiker aanspoort tot het bijwerken van de login" }, "turnOnAutofill": { "message": "Automatisch invullen inschakelen" @@ -4080,7 +4080,7 @@ "message": "Actief account" }, "bitwardenAccount": { - "message": "Bitwarden-account" + "message": "Bitwarden account" }, "availableAccounts": { "message": "Beschikbare accounts" @@ -5096,7 +5096,7 @@ "message": "Extra breed" }, "sshKeyWrongPassword": { - "message": "Het door jou ingevoerde wachtwoord is onjuist." + "message": "Het wachtwoord dat je hebt ingevoerd is onjuist." }, "importSshKey": { "message": "Importeren" @@ -5117,7 +5117,7 @@ "message": "Het type SSH-sleutel is niet ondersteund" }, "importSshKeyFromClipboard": { - "message": "Sleutel van klembord importeren" + "message": "Sleutel importeren van klembord" }, "sshKeyImported": { "message": "SSH-sleutel succesvol geïmporteerd" diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 4595b20ddbf..bdfaeb92531 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -2208,7 +2208,7 @@ "message": "项目已恢复" }, "alreadyHaveAccount": { - "message": "已经拥有账户了吗?" + "message": "已经有账户了吗?" }, "vaultTimeoutLogOutConfirmation": { "message": "超时后注销账户将解除对密码库的所有访问权限,并需要进行在线身份验证。确定使用此设置吗?" @@ -3628,7 +3628,7 @@ "message": "正在获取选项..." }, "multiSelectNotFound": { - "message": "未找到任何条目" + "message": "未找到任何项目" }, "multiSelectClearAll": { "message": "清除全部" @@ -4209,7 +4209,7 @@ "message": "建议的项目" }, "autofillSuggestionsTip": { - "message": "将此站点保存为登录项目以用于自动填充" + "message": "为这个站点保存一个登录项目以自动填充" }, "yourVaultIsEmpty": { "message": "您的密码库是空的" From d4116c05d7ac03ae474ba93aaad052a5c2718a34 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 10:28:51 +0100 Subject: [PATCH 3/6] Autosync the updated translations (#13962) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/nl/messages.json | 10 +++++----- apps/web/src/locales/zh_CN/messages.json | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index d193b2496f3..6b752b5a195 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -9847,13 +9847,13 @@ "message": "Lees meer over Bitwarden's API" }, "fileSend": { - "message": "Bestand verzenden" + "message": "Bestand Send" }, "fileSends": { "message": "Bestand-Sends" }, "textSend": { - "message": "Tekst-Sends" + "message": "Tekst Send" }, "textSends": { "message": "Tekst-Sends" @@ -10382,7 +10382,7 @@ "message": "Bitwarden-browserextensie openen" }, "somethingWentWrong": { - "message": "Er is iets fout gegaan..." + "message": "Er is iets fout gegaan…" }, "openingExtensionError": { "message": "We konden de Bitwarden-browserextensie niet openen. Klik op de knop om deze nu te openen." @@ -10407,7 +10407,7 @@ "description": "This will be used as part of a larger sentence, broken up to include the Bitwarden icon. The full sentence will read 'We had trouble opening the Bitwarden browser extension. Open the Bitwarden icon [Bitwarden Icon] from the toolbar.'" }, "openExtensionManuallyPart2": { - "message": "vanaf de werkbank.", + "message": "vanaf de werkbalk.", "description": "This will be used as part of a larger sentence, broken up to include the Bitwarden icon. The full sentence will read 'We had trouble opening the Bitwarden browser extension. Open the Bitwarden icon [Bitwarden Icon] from the toolbar.'" }, "resellerRenewalWarningMsg": { @@ -10542,7 +10542,7 @@ "message": "Upgrade voor echte event log gegevens" }, "upgradeEventLogMessage": { - "message": "Deze events zijn voorbeelden en weerspiegelen geen echte evenementen binnen je Bitwarden-organisatie." + "message": "Deze evenementen zijn alleen voorbeelden en weerspiegelen geen echte evenementen binnen je Bitwarden organisatie." }, "cannotCreateCollection": { "message": "Gratis organisaties kunnen maximaal twee collecties hebben. Upgrade naar een betaald abonnement voor het toevoegen van meer collecties." diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index bce969ee722..00bf9bc5973 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -2500,7 +2500,7 @@ } }, "noInactive2fa": { - "message": "没有在您的密码库发现未配置两步登录的网站。" + "message": "在您的密码库中没有发现未配置两步登录的网站。" }, "instructions": { "message": "说明" @@ -2596,7 +2596,7 @@ } }, "noReusedPasswords": { - "message": "您密码库中没有密码重复使用的项目。" + "message": "您密码库中没有密码重复使用的登录项目。" }, "timesReused": { "message": "重复使用次数" @@ -7921,7 +7921,7 @@ } }, "domainNotVerifiedEvent": { - "message": "$DOMAIN$ 未验证", + "message": "$DOMAIN$ 无法验证", "placeholders": { "DOMAIN": { "content": "$1", @@ -8779,7 +8779,7 @@ "description": "Label for field requesting a self-hosted integration service URL" }, "alreadyHaveAccount": { - "message": "已经拥有账户了吗?" + "message": "已经有账户了吗?" }, "toggleSideNavigation": { "message": "切换侧边导航" @@ -10294,7 +10294,7 @@ "message": "已声明" }, "domainStatusUnderVerification": { - "message": "正在验证" + "message": "验证中" }, "claimedDomainsDesc": { "message": "声明一个域名,以拥有电子邮箱地址与该域名匹配的所有成员账户。成员登录时将可以跳过 SSO 标识符。管理员也可以删除成员账户。" From a6e785d63cf71de0342446d29631efc8398bca5a Mon Sep 17 00:00:00 2001 From: Github Actions Date: Mon, 24 Mar 2025 10:49:32 +0000 Subject: [PATCH 4/6] Bumped client version(s) --- apps/web/package.json | 2 +- package-lock.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/package.json b/apps/web/package.json index 25890cf4b6e..2af524c92b7 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/web-vault", - "version": "2025.3.0", + "version": "2025.3.1", "scripts": { "build:oss": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", "build:bit": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" webpack -c ../../bitwarden_license/bit-web/webpack.config.js", diff --git a/package-lock.json b/package-lock.json index cb51c157b09..7331fcdde44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -243,7 +243,7 @@ }, "apps/web": { "name": "@bitwarden/web-vault", - "version": "2025.3.0" + "version": "2025.3.1" }, "libs/admin-console": { "name": "@bitwarden/admin-console", From 8e455007c028db3f98cd2affed6a7fd63e5f6331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 24 Mar 2025 12:50:11 +0100 Subject: [PATCH 5/6] PM-19095: Wire passkey autofill to UI (#13051) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Passkey stuff Co-authored-by: Anders Åberg * Ugly hacks * Work On Modal State Management * Applying modalStyles * modal * Improved hide/show * fixed promise * File name * fix prettier * Protecting against null API's and undefined data * Only show fake popup to devs * cleanup mock code * rename minmimal-app to modal-app * Added comment * Added comment * removed old comment * Avoided changing minimum size * Add small comment * Rename component * adress feedback * Fixed uppercase file * Fixed build * Added codeowners * added void * commentary * feat: reset setting on app start * Moved reset to be in main / process launch * Add comment to create window * Added a little bit of styling * Use Messaging service to loadUrl * Enable passkeysautofill * Add logging * halfbaked * Integration working * And now it works without extra delay * Clean up * add note about messaging * lb * removed console.logs * Cleanup and adress review feedback * This hides the swift UI * pick credential, draft * Remove logger * a whole lot of wiring * not working * Improved wiring * Cancel after 90s * Introduced observable * Launching bitwarden if its not running * Passing position from native to electron * Rename inModalMode to modalMode * remove tap * revert spaces * added back isDev * cleaned up a bit * Cleanup swift file * tweaked logging * clean up * Update apps/desktop/macos/autofill-extension/CredentialProviderViewController.swift Co-authored-by: Andreas Coroiu * Update apps/desktop/src/platform/main/autofill/native-autofill.main.ts Co-authored-by: Andreas Coroiu * Update apps/desktop/src/platform/services/desktop-settings.service.ts Co-authored-by: Andreas Coroiu * adress position feedback * Update apps/desktop/macos/autofill-extension/CredentialProviderViewController.swift Co-authored-by: Andreas Coroiu * Removed extra logging * Adjusted error logging * Use .error to log errors * remove dead code * Update desktop-autofill.service.ts * use parseCredentialId instead of guidToRawFormat * Update apps/desktop/src/autofill/services/desktop-autofill.service.ts Co-authored-by: Andreas Coroiu * Change windowXy to a Record instead of [number,number] * Update apps/desktop/src/autofill/services/desktop-fido2-user-interface.service.ts Co-authored-by: Andreas Coroiu * Remove unsued dep and comment * changed timeout to be spec recommended maxium, 10 minutes, for now. * Correctly assume UP * Removed extra cancelRequest in deinint * Add timeout and UV to confirmChoseCipher UV is performed by UI, not the service * Improved docs regarding undefined cipherId * cleanup: UP is no longer undefined * Run completeError if ipc messages conversion failed * don't throw, instead return undefined * Disabled passkey provider * Throw error if no activeUserId was found * removed comment * Fixed lint * removed unsued service * reset entitlement formatting * Update entitlements.mas.plist --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> Co-authored-by: Colton Hurst Co-authored-by: Andreas Coroiu Co-authored-by: Andreas Coroiu --- .../macos_provider/src/assertion.rs | 14 +- .../desktop_native/macos_provider/src/lib.rs | 20 +- .../macos_provider/src/registration.rs | 3 +- apps/desktop/desktop_native/napi/index.d.ts | 15 +- apps/desktop/desktop_native/napi/src/lib.rs | 48 ++++ .../CredentialProviderViewController.xib | 23 +- .../CredentialProviderViewController.swift | 261 ++++++++++++------ apps/desktop/src/app/app-routing.module.ts | 4 + .../components/fido2placeholder.component.ts | 90 +++++- .../src/app/services/services.module.ts | 17 +- apps/desktop/src/autofill/preload.ts | 38 +++ .../services/desktop-autofill.service.ts | 153 ++++++---- .../desktop-fido2-user-interface.service.ts | 191 ++++++++++++- apps/desktop/src/main.ts | 12 +- apps/desktop/src/main/messaging.main.ts | 4 + apps/desktop/src/main/tray.main.ts | 36 +-- apps/desktop/src/main/window.main.ts | 42 ++- .../main/autofill/native-autofill.main.ts | 17 +- .../platform/models/domain/window-state.ts | 5 + .../src/platform/popup-modal-styles.ts | 20 +- .../services/desktop-settings.service.ts | 19 +- ...ido2-user-interface.service.abstraction.ts | 2 +- 22 files changed, 826 insertions(+), 208 deletions(-) diff --git a/apps/desktop/desktop_native/macos_provider/src/assertion.rs b/apps/desktop/desktop_native/macos_provider/src/assertion.rs index 762ceaaed48..c5b43bb87fa 100644 --- a/apps/desktop/desktop_native/macos_provider/src/assertion.rs +++ b/apps/desktop/desktop_native/macos_provider/src/assertion.rs @@ -2,11 +2,22 @@ use std::sync::Arc; use serde::{Deserialize, Serialize}; -use crate::{BitwardenError, Callback, UserVerification}; +use crate::{BitwardenError, Callback, Position, UserVerification}; #[derive(uniffi::Record, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct PasskeyAssertionRequest { + rp_id: String, + client_data_hash: Vec, + user_verification: UserVerification, + allowed_credentials: Vec>, + window_xy: Position, + //extension_input: Vec, TODO: Implement support for extensions +} + +#[derive(uniffi::Record, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PasskeyAssertionWithoutUserInterfaceRequest { rp_id: String, credential_id: Vec, user_name: String, @@ -14,6 +25,7 @@ pub struct PasskeyAssertionRequest { record_identifier: Option, client_data_hash: Vec, user_verification: UserVerification, + window_xy: Position, } #[derive(uniffi::Record, Serialize, Deserialize)] diff --git a/apps/desktop/desktop_native/macos_provider/src/lib.rs b/apps/desktop/desktop_native/macos_provider/src/lib.rs index 5623436d874..8f2499ae68d 100644 --- a/apps/desktop/desktop_native/macos_provider/src/lib.rs +++ b/apps/desktop/desktop_native/macos_provider/src/lib.rs @@ -15,7 +15,10 @@ uniffi::setup_scaffolding!(); mod assertion; mod registration; -use assertion::{PasskeyAssertionRequest, PreparePasskeyAssertionCallback}; +use assertion::{ + PasskeyAssertionRequest, PasskeyAssertionWithoutUserInterfaceRequest, + PreparePasskeyAssertionCallback, +}; use registration::{PasskeyRegistrationRequest, PreparePasskeyRegistrationCallback}; #[derive(uniffi::Enum, Debug, Serialize, Deserialize)] @@ -26,6 +29,13 @@ pub enum UserVerification { Discouraged, } +#[derive(uniffi::Record, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Position { + pub x: i32, + pub y: i32, +} + #[derive(Debug, uniffi::Error, Serialize, Deserialize)] pub enum BitwardenError { Internal(String), @@ -141,6 +151,14 @@ impl MacOSProviderClient { ) { self.send_message(request, Box::new(callback)); } + + pub fn prepare_passkey_assertion_without_user_interface( + &self, + request: PasskeyAssertionWithoutUserInterfaceRequest, + callback: Arc, + ) { + self.send_message(request, Box::new(callback)); + } } #[derive(Serialize, Deserialize)] diff --git a/apps/desktop/desktop_native/macos_provider/src/registration.rs b/apps/desktop/desktop_native/macos_provider/src/registration.rs index d484af58b6c..9e697b75c16 100644 --- a/apps/desktop/desktop_native/macos_provider/src/registration.rs +++ b/apps/desktop/desktop_native/macos_provider/src/registration.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use serde::{Deserialize, Serialize}; -use crate::{BitwardenError, Callback, UserVerification}; +use crate::{BitwardenError, Callback, Position, UserVerification}; #[derive(uniffi::Record, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -13,6 +13,7 @@ pub struct PasskeyRegistrationRequest { client_data_hash: Vec, user_verification: UserVerification, supported_algorithms: Vec, + window_xy: Position, } #[derive(uniffi::Record, Serialize, Deserialize)] diff --git a/apps/desktop/desktop_native/napi/index.d.ts b/apps/desktop/desktop_native/napi/index.d.ts index 92f31cf5f89..ca1fe29e254 100644 --- a/apps/desktop/desktop_native/napi/index.d.ts +++ b/apps/desktop/desktop_native/napi/index.d.ts @@ -118,6 +118,10 @@ export declare namespace autofill { Required = 'required', Discouraged = 'discouraged' } + export interface Position { + x: number + y: number + } export interface PasskeyRegistrationRequest { rpId: string userName: string @@ -125,6 +129,7 @@ export declare namespace autofill { clientDataHash: Array userVerification: UserVerification supportedAlgorithms: Array + windowXy: Position } export interface PasskeyRegistrationResponse { rpId: string @@ -133,6 +138,13 @@ export declare namespace autofill { attestationObject: Array } export interface PasskeyAssertionRequest { + rpId: string + clientDataHash: Array + userVerification: UserVerification + allowedCredentials: Array> + windowXy: Position + } + export interface PasskeyAssertionWithoutUserInterfaceRequest { rpId: string credentialId: Array userName: string @@ -140,6 +152,7 @@ export declare namespace autofill { recordIdentifier?: string clientDataHash: Array userVerification: UserVerification + windowXy: Position } export interface PasskeyAssertionResponse { rpId: string @@ -156,7 +169,7 @@ export declare namespace autofill { * @param name The endpoint name to listen on. This name uniquely identifies the IPC connection and must be the same for both the server and client. * @param callback This function will be called whenever a message is received from a client. */ - static listen(name: string, registrationCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyRegistrationRequest) => void, assertionCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyAssertionRequest) => void): Promise + static listen(name: string, registrationCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyRegistrationRequest) => void, assertionCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyAssertionRequest) => void, assertionWithoutUserInterfaceCallback: (error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyAssertionWithoutUserInterfaceRequest) => void): Promise /** Return the path to the IPC server. */ getPath(): string /** Stop the IPC server. */ diff --git a/apps/desktop/desktop_native/napi/src/lib.rs b/apps/desktop/desktop_native/napi/src/lib.rs index d0c859d427c..f02be2b27b6 100644 --- a/apps/desktop/desktop_native/napi/src/lib.rs +++ b/apps/desktop/desktop_native/napi/src/lib.rs @@ -515,6 +515,14 @@ pub mod autofill { pub value: Result, } + #[napi(object)] + #[derive(Debug, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + pub struct Position { + pub x: i32, + pub y: i32, + } + #[napi(object)] #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -525,6 +533,7 @@ pub mod autofill { pub client_data_hash: Vec, pub user_verification: UserVerification, pub supported_algorithms: Vec, + pub window_xy: Position, } #[napi(object)] @@ -541,6 +550,18 @@ pub mod autofill { #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct PasskeyAssertionRequest { + pub rp_id: String, + pub client_data_hash: Vec, + pub user_verification: UserVerification, + pub allowed_credentials: Vec>, + pub window_xy: Position, + //extension_input: Vec, TODO: Implement support for extensions + } + + #[napi(object)] + #[derive(Debug, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + pub struct PasskeyAssertionWithoutUserInterfaceRequest { pub rp_id: String, pub credential_id: Vec, pub user_name: String, @@ -548,6 +569,7 @@ pub mod autofill { pub record_identifier: Option, pub client_data_hash: Vec, pub user_verification: UserVerification, + pub window_xy: Position, } #[napi(object)] @@ -592,6 +614,13 @@ pub mod autofill { (u32, u32, PasskeyAssertionRequest), ErrorStrategy::CalleeHandled, >, + #[napi( + ts_arg_type = "(error: null | Error, clientId: number, sequenceNumber: number, message: PasskeyAssertionWithoutUserInterfaceRequest) => void" + )] + assertion_without_user_interface_callback: ThreadsafeFunction< + (u32, u32, PasskeyAssertionWithoutUserInterfaceRequest), + ErrorStrategy::CalleeHandled, + >, ) -> napi::Result { let (send, mut recv) = tokio::sync::mpsc::channel::(32); tokio::spawn(async move { @@ -628,6 +657,25 @@ pub mod autofill { } } + match serde_json::from_str::< + PasskeyMessage, + >(&message) + { + Ok(msg) => { + let value = msg + .value + .map(|value| (client_id, msg.sequence_number, value)) + .map_err(|e| napi::Error::from_reason(format!("{e:?}"))); + + assertion_without_user_interface_callback + .call(value, ThreadsafeFunctionCallMode::NonBlocking); + continue; + } + Err(e) => { + println!("[ERROR] Error deserializing message1: {e}"); + } + } + match serde_json::from_str::>( &message, ) { diff --git a/apps/desktop/macos/autofill-extension/Base.lproj/CredentialProviderViewController.xib b/apps/desktop/macos/autofill-extension/Base.lproj/CredentialProviderViewController.xib index ace3497a58b..1e47cc54de2 100644 --- a/apps/desktop/macos/autofill-extension/Base.lproj/CredentialProviderViewController.xib +++ b/apps/desktop/macos/autofill-extension/Base.lproj/CredentialProviderViewController.xib @@ -1,22 +1,23 @@ - + - + + - + - +