diff --git a/renovate.json b/.github/renovate.json similarity index 100% rename from renovate.json rename to .github/renovate.json diff --git a/.github/whitelist-capital-letters.txt b/.github/whitelist-capital-letters.txt index 247107e87e8..772c7209e20 100644 --- a/.github/whitelist-capital-letters.txt +++ b/.github/whitelist-capital-letters.txt @@ -123,7 +123,6 @@ ./libs/common/src/importers/dashlaneImporters/dashlaneCsvImporter.ts ./libs/common/src/importers/dashlaneImporters/types/dashlaneCsvTypes.ts ./libs/common/src/importers/dashlaneImporters/dashlaneJsonImporter.ts -./libs/common/src/importers/chromeCsvImporter.ts ./libs/common/src/importers/meldiumCsvImporter.ts ./libs/common/src/importers/safariCsvImporter.ts ./libs/common/src/importers/msecureCsvImporter.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bb0b4453dfa..e5ff1343f2e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,3 +55,51 @@ jobs: - name: Run tests run: | npm run test + + rust: + name: rust - ${{ matrix.os }} + runs-on: ${{ matrix.os || 'ubuntu-latest' }} + + strategy: + matrix: + os: + - ubuntu-latest + - macos-latest + - windows-latest + + steps: + - name: Install gnome-keyring + if: ${{ matrix.os=='ubuntu-latest' }} + run: sudo apt-get install -y gnome-keyring dbus-x11 + + - name: Checkout repo + uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 + + - name: Install rust + uses: actions-rs/toolchain@88dc2356392166efad76775c878094f4e83ff746 + with: + toolchain: stable + profile: minimal + override: true + + - name: Build + working-directory: ./apps/desktop/desktop_native + run: cargo build + + - name: Test Ubuntu + if: ${{ matrix.os=='ubuntu-latest' }} + working-directory: ./apps/desktop/desktop_native + run: | + eval "$(dbus-launch --sh-syntax)" + mkdir -p ~/.cache + mkdir -p ~/.local/share/keyrings + eval "$(printf '\n' | gnome-keyring-daemon --unlock)" + eval "$(printf '\n' | /usr/bin/gnome-keyring-daemon --start)" + cargo test -- --test-threads=1 + + - name: Test Windows / macOS + if: ${{ matrix.os!='ubuntu-latest' }} + working-directory: ./apps/desktop/desktop_native + run: | + cargo test -- --test-threads=1 + diff --git a/.storybook/main.js b/.storybook/main.js index e2e893f1afb..7c0d2d97a15 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -16,6 +16,7 @@ module.exports = { framework: "@storybook/angular", core: { builder: "webpack5", + disableTelemetry: true, }, webpackFinal: async (config, { configType }) => { config.resolve.plugins = [new TsconfigPathsPlugin()]; diff --git a/angular.json b/angular.json index 4e20f2294d8..a2b82cc64e9 100644 --- a/angular.json +++ b/angular.json @@ -2,6 +2,9 @@ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "apps", + "cli": { + "analytics": false + }, "projects": { "web": { "projectType": "application", diff --git a/apps/browser/package.json b/apps/browser/package.json index 83bce4648ad..50f71797a69 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/browser", - "version": "2022.10.1", + "version": "2022.10.2", "scripts": { "build": "webpack", "build:mv3": "cross-env MANIFEST_VERSION=3 webpack", diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index 82c78e830b7..6f0315bb6c2 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -537,13 +537,13 @@ "message": "Element afegit" }, "editedItem": { - "message": "Element editat" + "message": "Element guardat" }, "deleteItemConfirmation": { "message": "Esteu segur que voleu suprimir aquest element?" }, "deletedItem": { - "message": "Element suprimit" + "message": "Element enviat a la paperera" }, "overwritePassword": { "message": "Sobreescriu la contrasenya" @@ -732,13 +732,13 @@ "message": "No hi ha cap adjunt." }, "attachmentSaved": { - "message": "S'ha guardat el fitxer adjunt." + "message": "S'ha guardat el fitxer adjunt" }, "file": { "message": "Fitxer" }, "selectFile": { - "message": "Seleccioneu un fitxer." + "message": "Seleccioneu un fitxer" }, "maxFileSize": { "message": "La mida màxima del fitxer és de 500 MB." @@ -951,7 +951,7 @@ "message": "URL del servidor d'icones" }, "environmentSaved": { - "message": "S'han guardat les URL de l'entorn." + "message": "S'han guardat les URL de l'entorn" }, "enableAutoFillOnPageLoad": { "message": "Habilita l'emplenament automàtic en carregar la pàgina" @@ -1738,7 +1738,7 @@ "message": "Contrasenya nova" }, "sendDisabled": { - "message": "Send desactivat", + "message": "Send suprimit", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisabledWarning": { @@ -1750,7 +1750,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { - "message": "Send editat", + "message": "Send guardat", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { @@ -1857,7 +1857,7 @@ "message": "El temps d'espera de la caixa forta supera les restriccions establertes per la vostra organització." }, "vaultExportDisabled": { - "message": "L'exportació de la caixa forta està desactivada" + "message": "L'exportació de la caixa forta no està disponible" }, "personalVaultExportPolicyInEffect": { "message": "Una o més polítiques d'organització us impedeixen exportar la vostra caixa forta." @@ -1976,7 +1976,7 @@ "message": "Cal una subscripció premium" }, "organizationIsDisabled": { - "message": "L'organització està inhabilitada." + "message": "L'organització està suspesa." }, "disabledOrganizationFilterError": { "message": "No es pot accedir als elements de les organitzacions inhabilitades. Poseu-vos en contacte amb el propietari de la vostra organització per obtenir ajuda." diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index 67018e81e5d..72b1c925bd0 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -1312,7 +1312,7 @@ "description": "ex. Date this item was updated" }, "dateCreated": { - "message": "Created", + "message": "ایجاد شده", "description": "ex. Date this item was created" }, "datePasswordUpdated": { diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index fa51e48652d..c13047537c3 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -11,7 +11,7 @@ "description": "Extension description" }, "loginOrCreateNewAccount": { - "message": "Kirjaudu sisään tai luo uusi tili päästäksesi salattuun holviisi." + "message": "Kirjaudu tai luo uusi tili käyttääksesi salattua holviasi." }, "createAccount": { "message": "Luo tili" @@ -1488,10 +1488,10 @@ "message": "Valitsemalla tämän ruudun hyväksyt seuraavat:" }, "acceptPoliciesRequired": { - "message": "Käyttöehtoja ja tietosuojakäytäntöä ei ole vahvistettu." + "message": "Palveluehtoja ja tietosuojakäytäntöä ei ole vahvistettu." }, "termsOfService": { - "message": "Käyttöehdot" + "message": "Palveluehdot" }, "privacyPolicy": { "message": "Tietosuojakäytäntö" @@ -1640,7 +1640,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "disabled": { - "message": "Ei käytössä" + "message": "Poistettu käytöstä" }, "removePasswordConfirmation": { "message": "Haluatko varmasti poistaa salasanan?" @@ -1841,7 +1841,7 @@ "message": "Minuuttia" }, "vaultTimeoutPolicyInEffect": { - "message": "Organisaatiosi käytännöt vaikuttavat holvisi aikakatkaisuun. Suurin sallittu aika on $HOURS$ tunti(a) ja $MINUTES$ minuutti(a)", + "message": "Organisaatiokäytännöt vaikuttavat holvin aikakatkaisuun. Suurin sallittu aika on $HOURS$ tunti(a) ja $MINUTES$ minuutti(a)", "placeholders": { "hours": { "content": "$1", @@ -1884,7 +1884,7 @@ "message": "Poista pääsalasana" }, "removedMasterPassword": { - "message": "Pääsalasana on poistettiin" + "message": "Pääsalasana poistettiin" }, "leaveOrganizationConfirmation": { "message": "Haluatko varmasti poistua tästä organisaatiosta?" diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 62b28b4d675..fa14f56e8b5 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -1312,7 +1312,7 @@ "description": "ex. Date this item was updated" }, "dateCreated": { - "message": "Created", + "message": "Créé", "description": "ex. Date this item was created" }, "datePasswordUpdated": { diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 44d7249133f..dd38f0f5d02 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -927,7 +927,7 @@ "message": "A helyileg működtetett Bitwarden telepítés alap webcímének megadása." }, "customEnvironment": { - "message": "Egyéni környezet" + "message": "Egyedi környezet" }, "customEnvironmentFooter": { "message": "Haladó felhasználóknak. Minden egyes szolgáltatás alap URL-jét külön megadhatod." @@ -954,7 +954,7 @@ "message": "A környezeti webcímek mentésre kerültek." }, "enableAutoFillOnPageLoad": { - "message": "Automatikus kitöltés engedélyezése oldal betöltéskor" + "message": "Automatikus kitöltés oldalbetöltésnél" }, "enableAutoFillOnPageLoadDesc": { "message": "Ha egy bejelentkezési űrlap észlelésre került, az adatok automatikus kitöltése az oldal betöltésekor." @@ -1278,7 +1278,7 @@ "description": "Default URI match detection for auto-fill." }, "toggleOptions": { - "message": "Opciók megnyitása" + "message": "Opciók váltása" }, "toggleCurrentUris": { "message": "Aktuális URI elemek váltása", @@ -1384,7 +1384,7 @@ "message": "Legalább egy gyűjteményt ki kell választani." }, "cloneItem": { - "message": "Tétel klónozása" + "message": "Elem klónozása" }, "clone": { "message": "Klónozás" @@ -1509,19 +1509,19 @@ "message": "Ellenőrizzük, hogy az asztali alkalmazás megjeleníti-e ezt az ujjlenyomatot: " }, "desktopIntegrationDisabledTitle": { - "message": "A böngésző integráció nem engedélyezett." + "message": "A böngésző integráció nincs beüzemelve." }, "desktopIntegrationDisabledDesc": { - "message": "A böngésző integráció nincs engedélyezve a Bitwarden asztali alkalmazásban. Engedélyezzük az asztali alkalmazás beállításai között." + "message": "A böngésző integráció nincs beüzemelve a Bitwarden asztali alkalmazásban. Engedélyezzük az asztali alkalmazás beállításai között." }, "startDesktopTitle": { "message": "A Bitwarden asztali alkalmazás indítása" }, "startDesktopDesc": { - "message": "A funkció használatához el kell indítani a Bitwarden asztali alkalmazást." + "message": "A Bitwarden asztali alkalmazást el kell indítani a biometrikus adatokkal feloldás használatához." }, "errorEnableBiometricTitle": { - "message": "Nem lehet engedélyezni a biometrikus adatokat." + "message": "Nem lehet beüzemelni a biometrikus adatokat." }, "errorEnableBiometricDesc": { "message": "A műveletet az asztali alkalmazás törölte." @@ -1539,10 +1539,10 @@ "message": "A fiók nem egyezik." }, "biometricsNotEnabledTitle": { - "message": "A biometrikus adatok nincsenek engedélyezve." + "message": "A biometrikus adatok nincsenek beüzemelve." }, "biometricsNotEnabledDesc": { - "message": "A böngésző biometrikus adataihoz először az asztali biometrikus adatokat kell engedélyezni a beállításokban." + "message": "A böngésző biometrikus adataihoz először az asztali biometrikus adatokat kell beüzemelni a beállításokban." }, "biometricsNotSupportedTitle": { "message": "A biometrikus adatok nem támogatottak." @@ -1731,14 +1731,14 @@ "message": "Aktuális elérési szám" }, "createSend": { - "message": "Új Send létrehozása", + "message": "Új Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "newPassword": { "message": "Új jelszó" }, "sendDisabled": { - "message": "A Send kikapcsolásra került", + "message": "A Send eltávolításra került.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisabledWarning": { @@ -1750,7 +1750,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { - "message": "A Send szerkesztésre került", + "message": "A Send mentésre került.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index 18f2b2d8938..be7f898920f 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -1312,7 +1312,7 @@ "description": "ex. Date this item was updated" }, "dateCreated": { - "message": "Created", + "message": "Creato", "description": "ex. Date this item was created" }, "datePasswordUpdated": { diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 8db582bc209..0295bee2d7a 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -642,7 +642,7 @@ "description": "Light color" }, "solarizedDark": { - "message": "Tumšs Solarized", + "message": "Solarized Dark", "description": "'Solarized' is a noun and the name of a color scheme. It should not be translated." }, "exportVault": { diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 0714076bbda..625899d4bc8 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -1312,7 +1312,7 @@ "description": "ex. Date this item was updated" }, "dateCreated": { - "message": "Created", + "message": "Criado", "description": "ex. Date this item was created" }, "datePasswordUpdated": { @@ -2012,7 +2012,7 @@ "message": "Terceiros" }, "thirdPartyServerMessage": { - "message": "Connected to third-party server implementation, $SERVERNAME$. Please verify bugs using the official server, or report them to the third-party server.", + "message": "Conectado a implementação de servidores terceiros, $SERVERNAME$. Por favor, verifique as falhas usando o servidor oficial ou reporte-os ao servidor de terceiros.", "placeholders": { "servername": { "content": "$1", @@ -2021,7 +2021,7 @@ } }, "lastSeenOn": { - "message": "last seen on: $DATE$", + "message": "visto pela última vez: $DATE$", "placeholders": { "date": { "content": "$1", diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index 72b3150d4ef..2b958cc95ed 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -509,7 +509,7 @@ "message": "Посмотрите небольшой обучающий материал, чтобы узнать, как получить максимальную отдачу от расширения браузера." }, "syncingComplete": { - "message": "Синхронизация завершена" + "message": "Синхронизация выполнена" }, "syncingFailed": { "message": "Ошибка синхронизации" @@ -723,7 +723,7 @@ "message": "Вы действительно хотите удалить это вложение?" }, "deletedAttachment": { - "message": "Удаленное вложение" + "message": "Вложение удалено" }, "newAttachment": { "message": "Добавить новое вложение" @@ -753,19 +753,19 @@ "message": "Премиум" }, "premiumManage": { - "message": "Управление статусом" + "message": "Управление Премиум" }, "premiumManageAlert": { "message": "Вы можете управлять Премиум на bitwarden.com. Перейти на сайт сейчас?" }, "premiumRefresh": { - "message": "Обновить статус" + "message": "Обновить Премиум" }, "premiumNotCurrentMember": { - "message": "Сейчас вы не Премиум-участник." + "message": "Сейчас у вас отсутствует Премиум." }, "premiumSignUpAndGet": { - "message": "Подпишитесь на премиум-статус и получите:" + "message": "Подпишитесь на Премиум и получите:" }, "ppremiumSignUpStorage": { "message": "1 ГБ зашифрованного хранилища для вложенных файлов." @@ -783,16 +783,16 @@ "message": "Приоритетная поддержка." }, "ppremiumSignUpFuture": { - "message": "Все будущие функции премиум-статуса. Их будет больше!" + "message": "Все будущие функции Премиум. Их будет больше!" }, "premiumPurchase": { "message": "Купить Премиум" }, "premiumPurchaseAlert": { - "message": "Вы можете купить премиум-статус на bitwarden.com. Перейти на сайт сейчас?" + "message": "Вы можете купить Премиум на bitwarden.com. Перейти на сайт сейчас?" }, "premiumCurrentMember": { - "message": "У вас премиум-статус!" + "message": "У вас есть Премиум!" }, "premiumCurrentMemberThanks": { "message": "Благодарим вас за поддержку Bitwarden." @@ -873,13 +873,13 @@ "message": "Вход недоступен" }, "noTwoStepProviders": { - "message": "У аккаунта включена двухэтапная аутентификация, но ни один из настроенных вариантов не поддерживается этим веб-браузером." + "message": "У этой учетной записи включена двухфакторная аутентификация, однако ни один из настроенных вариантов не поддерживается этим веб-браузером." }, "noTwoStepProviders2": { "message": "Используйте поддерживаемый веб-браузер (например, Chrome) и/или добавьте дополнительные варианты аутентификации, которые поддерживаются в веб-браузерах (например, приложение-аутентификатор)." }, "twoStepOptions": { - "message": "Настройки двухэтапной аутентификации" + "message": "Настройки двухфакторной аутентификации" }, "recoveryCodeDesc": { "message": "Потеряли доступ ко всем вариантам двухфакторной аутентификации? Используйте код восстановления, чтобы отключить двухфакторную аутентификацию для вашей учетной записи." @@ -912,7 +912,7 @@ "message": "FIDO2 WebAuthn" }, "webAuthnDesc": { - "message": "Используйте любой ключ безопасности с поддержкой WebAuthn для доступа к своей учетной записи." + "message": "Используйте любой ключ безопасности с поддержкой WebAuthn для доступа к вашей учетной записи." }, "emailTitle": { "message": "Email" @@ -921,10 +921,10 @@ "message": "Коды подтверждения будут отправлены вам по электронной почте." }, "selfHostedEnvironment": { - "message": "Среда собственного хостинга" + "message": "Окружение собственного хостинга" }, "selfHostedEnvironmentFooter": { - "message": "Укажите URL-адрес Bitwarden на вашем сервере." + "message": "Укажите URL Bitwarden на вашем сервере." }, "customEnvironment": { "message": "Пользовательское окружение" @@ -933,25 +933,25 @@ "message": "Для опытных пользователей. Можно указать URL отдельно для каждой службы." }, "baseUrl": { - "message": "URL-адрес сервера" + "message": "URL сервера" }, "apiUrl": { - "message": "API URL-адреса сервера" + "message": "URL API сервера" }, "webVaultUrl": { - "message": "URL-адрес сервера веб-хранилища" + "message": "URL сервера веб-хранилища" }, "identityUrl": { - "message": "URL-адрес сервера идентификации" + "message": "URL сервера идентификации" }, "notificationsUrl": { - "message": "URL-адрес сервера уведомлений" + "message": "URL сервера уведомлений" }, "iconsUrl": { - "message": "URL-адрес сервера значков" + "message": "URL сервера значков" }, "environmentSaved": { - "message": "URL-адреса среды сохранены." + "message": "URL окружения сохранены" }, "enableAutoFillOnPageLoad": { "message": "Автозаполнение при загрузке страницы" @@ -1434,10 +1434,10 @@ "message": "Заполнить и сохранить" }, "autoFillSuccessAndSavedUri": { - "message": "Автозаполненный элемент и сохраненный URI" + "message": "URI элемента заполнен и сохранен" }, "autoFillSuccess": { - "message": "Автозаполненный элемент" + "message": "Элемент заполнен " }, "setMasterPassword": { "message": "Задать мастер-пароль" @@ -1509,10 +1509,10 @@ "message": "Пожалуйста, убедитесь, что приложение для компьютера отображает этот отпечаток: " }, "desktopIntegrationDisabledTitle": { - "message": "Интеграция с браузером не включена" + "message": "Интеграция с браузером не настроена" }, "desktopIntegrationDisabledDesc": { - "message": "Пожалуйста, включите интеграцию с браузером в настройках приложения Bitwarden для компьютера." + "message": "Пожалуйста, настройте интеграцию с браузером в приложени Bitwarden для компьютера." }, "startDesktopTitle": { "message": "Запустить приложение Bitwarden для компьютера" @@ -1521,7 +1521,7 @@ "message": "Перед использованием разблокировки с помощью биометрии необходимо запустить приложение Bitwarden для компьютера." }, "errorEnableBiometricTitle": { - "message": "Не удается включить биометрию" + "message": "Не удается настроить биометрию" }, "errorEnableBiometricDesc": { "message": "Действие было отменено приложением для компьютера" @@ -1539,7 +1539,7 @@ "message": "Несоответствие аккаунта" }, "biometricsNotEnabledTitle": { - "message": "Биометрия не включена" + "message": "Биометрия не настроена" }, "biometricsNotEnabledDesc": { "message": "Для активации биометрии в браузере сначала необходимо включить биометрию в приложении для компьютера." @@ -1632,7 +1632,7 @@ "message": "Пароль удален" }, "deletedSend": { - "message": "Удаленная Send", + "message": "Send удалена", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLink": { @@ -1669,14 +1669,14 @@ "message": "Файл, который вы хотите отправить." }, "deletionDate": { - "message": "Срок удаления" + "message": "Дата удаления" }, "deletionDateDesc": { "message": "Эта Send будет окончательно удалена в указанные дату и время.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { - "message": "Срок истечения" + "message": "Дата истечения" }, "expirationDateDesc": { "message": "Если задано, доступ к этой Send истечет в указанные дату и время.", @@ -1713,7 +1713,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisableDesc": { - "message": "Отключить эту Send, чтобы никто не мог получить к ней доступ.", + "message": "Деактивировать эту Send, чтобы никто не мог получить к ней доступ.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendShareDesc": { @@ -1728,17 +1728,17 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "currentAccessCount": { - "message": "Текущих обращений" + "message": "Счетчик текущих обращений" }, "createSend": { - "message": "Создание новой Send", + "message": "Новая Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "newPassword": { "message": "Новый пароль" }, "sendDisabled": { - "message": "Send отключена", + "message": "Send удалена", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisabledWarning": { @@ -1746,11 +1746,11 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createdSend": { - "message": "Созданная Send", + "message": "Send создана", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { - "message": "Измененная Send", + "message": "Send сохранена", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { @@ -1823,7 +1823,7 @@ "message": "Мастер-пароль недавно был изменен администратором вашей организации. Чтобы получить доступ к хранилищу, вы должны обновить его сейчас. В результате текущая сессия будет завершена, потребуется повторный вход. Активные сессии на других устройствах могут оставаться активными в течение одного часа." }, "resetPasswordPolicyAutoEnroll": { - "message": "Автоматическая регистрация" + "message": "Автоматическое развертывание" }, "resetPasswordAutoEnrollInviteWarning": { "message": "В этой организации действует корпоративная политика, которая автоматически зарегистрирует вас на сброс пароля. Регистрация позволит администраторам организации изменить ваш мастер-пароль." @@ -1857,10 +1857,10 @@ "message": "Тайм-аут вашего хранилища превышает ограничения, установленные вашей организацией." }, "vaultExportDisabled": { - "message": "Экспорт хранилища отключен" + "message": "Экспорт хранилища недоступен" }, "personalVaultExportPolicyInEffect": { - "message": "Экспорт вашего личного хранилища запрещен одной или несколькими политиками организации." + "message": "Одна или несколько политик организации запрещают вам экспортировать личное хранилище." }, "copyCustomFieldNameInvalidElement": { "message": "Невозможно определить элемент формы. Попробуйте вместо этого проверить HTML." @@ -1884,7 +1884,7 @@ "message": "Удалить мастер-пароль" }, "removedMasterPassword": { - "message": "Мастер-пароль удален." + "message": "Мастер-пароль удален" }, "leaveOrganizationConfirmation": { "message": "Вы действительно хотите покинуть эту организацию?" @@ -1930,10 +1930,10 @@ "message": "Используйте возможности субадресации вашей электронной почты." }, "catchallEmail": { - "message": "Catch-all-адрес электронной почты" + "message": "Общий email домена" }, "catchallEmailDesc": { - "message": "Использовать настроенную в вашем домене почту catch-all." + "message": "Использовать общую почту домена." }, "random": { "message": "Случайно" diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 459ffad893d..5615620ed55 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -1312,7 +1312,7 @@ "description": "ex. Date this item was updated" }, "dateCreated": { - "message": "Created", + "message": "Креирано", "description": "ex. Date this item was created" }, "datePasswordUpdated": { diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 007e0a45703..1b80efbb577 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -153,7 +153,7 @@ "description": "A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing." }, "yourAccountsFingerprint": { - "message": "Фраза відбитку вашого облікового запису", + "message": "Фраза відбитка вашого облікового запису", "description": "A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing." }, "twoStepLogin": { @@ -181,7 +181,7 @@ "message": "Назва" }, "editFolder": { - "message": "Редагувати теку" + "message": "Редагування" }, "deleteFolder": { "message": "Видалити теку" @@ -303,7 +303,7 @@ "message": "Нотатка" }, "editItem": { - "message": "Редагування запису" + "message": "Редагування" }, "folder": { "message": "Тека" @@ -321,7 +321,7 @@ "message": "Вебсайт" }, "toggleVisibility": { - "message": "Змінити видимість" + "message": "Перемкнути видимість" }, "manage": { "message": "Керування" @@ -512,7 +512,7 @@ "message": "Синхронізацію завершено" }, "syncingFailed": { - "message": "Не вдалося синхронізувати" + "message": "Збій синхронізації" }, "passwordCopied": { "message": "Пароль скопійовано" @@ -537,7 +537,7 @@ "message": "Запис додано" }, "editedItem": { - "message": "Запис змінено" + "message": "Запис збережено" }, "deleteItemConfirmation": { "message": "Ви дійсно хочете перенести до смітника?" @@ -873,7 +873,7 @@ "message": "Вхід недоступний" }, "noTwoStepProviders": { - "message": "Для цього облікового запису увімкнено двоетапну перевірку. Однак, жоден з налаштованих провайдерів двоетапної перевірки не підтримується цим браузером." + "message": "Для цього облікового запису увімкнено двоетапну перевірку. Однак, жоден із налаштованих провайдерів не підтримується цим браузером." }, "noTwoStepProviders2": { "message": "Будь ласка, скористайтеся підтримуваним браузером (наприклад, Chrome) та/або іншими провайдерами, що краще підтримуються браузерами (наприклад, програма авторизації)." @@ -936,7 +936,7 @@ "message": "URL-адреса сервера" }, "apiUrl": { - "message": "URL-адреса API" + "message": "URL-адреса сервера API" }, "webVaultUrl": { "message": "URL-адреса сервера веб сховища" @@ -945,13 +945,13 @@ "message": "URL-адреса сервера ідентифікації" }, "notificationsUrl": { - "message": "URL сервера сповіщень" + "message": "URL-адреса сервера сповіщень" }, "iconsUrl": { "message": "URL-адреса сервера піктограм" }, "environmentSaved": { - "message": "URL-адреси середовища збережено." + "message": "URL-адреси середовища збережено" }, "enableAutoFillOnPageLoad": { "message": "Автозаповнення на сторінці" @@ -1375,7 +1375,7 @@ "message": "Очікується підтвердження з комп'ютера" }, "awaitDesktopDesc": { - "message": "Для увімкнення біометрії в браузері, будь ласка, підтвердьте це у програмі Bitwarden на комп'ютері." + "message": "Щоб увімкнути біометрію в браузері, спершу виконайте це у програмі Bitwarden на комп'ютері." }, "lockWithMasterPassOnRestart": { "message": "Блокувати головним паролем при перезапуску браузера" @@ -1506,13 +1506,13 @@ "message": "Перевірка синхронізації на комп'ютері" }, "desktopIntegrationVerificationText": { - "message": "Перевірте, чи програма на комп'ютері показує відбиток: " + "message": "Перевірте, чи програма на комп'ютері показує цю фразу відбитка: " }, "desktopIntegrationDisabledTitle": { - "message": "Інтеграція з браузером не увімкнена" + "message": "Інтеграцію з браузером не налаштовано" }, "desktopIntegrationDisabledDesc": { - "message": "Інтеграція з браузером не увімкнена в програмі Bitwarden на комп'ютері. Увімкніть її в налаштуваннях програми на комп'ютері." + "message": "Інтеграцію з браузером не налаштовано в Bitwarden на комп'ютері. Увімкніть її в налаштуваннях програми на комп'ютері." }, "startDesktopTitle": { "message": "Запустіть програму Bitwarden на комп'ютері" @@ -1521,7 +1521,7 @@ "message": "Для можливості розблокування з біометрією необхідно запустити програму Bitwarden на комп'ютері." }, "errorEnableBiometricTitle": { - "message": "Не вдається увімкнути біометрію" + "message": "Не вдається налаштувати біометрію" }, "errorEnableBiometricDesc": { "message": "Дію було скасовано програмою на комп'ютері" @@ -1539,10 +1539,10 @@ "message": "Невідповідність облікових записів" }, "biometricsNotEnabledTitle": { - "message": "Біометрію не увімкнено" + "message": "Біометрію не налаштовано" }, "biometricsNotEnabledDesc": { - "message": "Для активації біометрії в браузері необхідно спершу увімкнути біометрію в програмі на комп'ютері." + "message": "Для використання біометрії в браузері необхідно спершу налаштувати її в програмі на комп'ютері." }, "biometricsNotSupportedTitle": { "message": "Біометрія не підтримується" @@ -1654,7 +1654,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editSend": { - "message": "Змінити відправлення", + "message": "Редагування", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendTypeHeader": { @@ -1731,14 +1731,14 @@ "message": "Поточна кількість доступів" }, "createSend": { - "message": "Створити нове відправлення", + "message": "Нове відправлення", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "newPassword": { "message": "Новий пароль" }, "sendDisabled": { - "message": "Відправлення вимкнено", + "message": "Відправлення вилучено", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisabledWarning": { @@ -1750,7 +1750,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { - "message": "Відправлення змінено", + "message": "Відправлення збережено", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { @@ -1857,7 +1857,7 @@ "message": "Час очікування сховища перевищує обмеження, встановлені вашою організацією." }, "vaultExportDisabled": { - "message": "Експорт сховища вимкнено" + "message": "Експорт сховища недоступний" }, "personalVaultExportPolicyInEffect": { "message": "Одна чи декілька організаційних політик не дозволяють вам експортувати особисте сховище." @@ -1884,7 +1884,7 @@ "message": "Вилучити головний пароль" }, "removedMasterPassword": { - "message": "Головний пароль вилучено." + "message": "Головний пароль вилучено" }, "leaveOrganizationConfirmation": { "message": "Ви справді хочете покинути цю організацію?" diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index 60ce0f000c8..5229d021a2f 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -248,7 +248,7 @@ "message": "特殊字元 (!@#$%^&*)" }, "numWords": { - "message": "單詞數量" + "message": "單字數量" }, "wordSeparator": { "message": "單詞分隔字元" diff --git a/apps/browser/src/background/notification.background.ts b/apps/browser/src/background/notification.background.ts index 569a77abe70..127fc5203d7 100644 --- a/apps/browser/src/background/notification.background.ts +++ b/apps/browser/src/background/notification.background.ts @@ -7,6 +7,7 @@ import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.serv import { AuthenticationStatus } from "@bitwarden/common/enums/authenticationStatus"; import { CipherType } from "@bitwarden/common/enums/cipherType"; import { PolicyType } from "@bitwarden/common/enums/policyType"; +import { ThemeType } from "@bitwarden/common/enums/themeType"; import { Utils } from "@bitwarden/common/misc/utils"; import { CipherView } from "@bitwarden/common/models/view/cipher.view"; import { LoginUriView } from "@bitwarden/common/models/view/login-uri.view"; @@ -125,13 +126,13 @@ export default class NotificationBackground { } if (tab != null) { - this.doNotificationQueueCheck(tab); + await this.doNotificationQueueCheck(tab); return; } const currentTab = await BrowserApi.getTabFromCurrentWindow(); if (currentTab != null) { - this.doNotificationQueueCheck(currentTab); + await this.doNotificationQueueCheck(currentTab); } } @@ -144,7 +145,7 @@ export default class NotificationBackground { setTimeout(() => this.cleanupNotificationQueue(), 2 * 60 * 1000); // check every 2 minutes } - private doNotificationQueueCheck(tab: chrome.tabs.Tab): void { + private async doNotificationQueueCheck(tab: chrome.tabs.Tab): Promise { if (tab == null) { return; } @@ -167,6 +168,7 @@ export default class NotificationBackground { type: "add", typeData: { isVaultLocked: this.notificationQueue[i].wasVaultLocked, + theme: await this.getCurrentTheme(), }, }); } else if (this.notificationQueue[i].type === NotificationQueueMessageType.ChangePassword) { @@ -174,6 +176,7 @@ export default class NotificationBackground { type: "change", typeData: { isVaultLocked: this.notificationQueue[i].wasVaultLocked, + theme: await this.getCurrentTheme(), }, }); } @@ -181,6 +184,18 @@ export default class NotificationBackground { } } + private async getCurrentTheme() { + const theme = await this.stateService.getTheme(); + + if (theme !== ThemeType.System) { + return theme; + } + + return window.matchMedia("(prefers-color-scheme: dark)").matches + ? ThemeType.Dark + : ThemeType.Light; + } + private removeTabFromNotificationQueue(tab: chrome.tabs.Tab) { for (let i = this.notificationQueue.length - 1; i >= 0; i--) { if (this.notificationQueue[i].tabId === tab.id) { @@ -394,7 +409,7 @@ export default class NotificationBackground { } const cipher = await this.cipherService.encrypt(model); - await this.cipherService.saveWithServer(cipher); + await this.cipherService.createWithServer(cipher); } private async getDecryptedCipherById(cipherId: string) { @@ -409,7 +424,7 @@ export default class NotificationBackground { if (cipher != null && cipher.type === CipherType.Login) { cipher.login.password = newPassword; const newCipher = await this.cipherService.encrypt(cipher); - await this.cipherService.saveWithServer(newCipher); + await this.cipherService.updateWithServer(newCipher); } } diff --git a/apps/browser/src/content/autofill.js b/apps/browser/src/content/autofill.js index d4c05f7e8ce..d7b9db2aeb4 100644 --- a/apps/browser/src/content/autofill.js +++ b/apps/browser/src/content/autofill.js @@ -40,6 +40,7 @@ 7. Remove "some useful globals" on window 8. Add ability to autofill span[data-bwautofill] elements 9. Add new handler, for new command that responds with page details in response callback + 10. Handle sandbox iframe and sandbox rule in CSP */ function collect(document, undefined) { @@ -641,6 +642,12 @@ 0 == confirmResult)) ? true : false; } + // Detect if within an iframe, and the iframe is sandboxed + function isSandboxed() { + // self.origin is 'null' if inside a frame with sandboxed csp or iframe tag + return self.origin == null || self.origin === 'null'; + } + function doFill(fillScript) { var fillScriptOps, theOpIds = [], @@ -653,7 +660,7 @@ fillScriptProperties.delay_between_operations && (operationDelayMs = fillScriptProperties.delay_between_operations); - if (urlNotSecure(fillScript.savedURL)) { + if (isSandboxed() || urlNotSecure(fillScript.savedURL)) { return; } diff --git a/apps/browser/src/content/notificationBar.ts b/apps/browser/src/content/notificationBar.ts index 92730e16292..76a8a7c277e 100644 --- a/apps/browser/src/content/notificationBar.ts +++ b/apps/browser/src/content/notificationBar.ts @@ -498,17 +498,13 @@ document.addEventListener("DOMContentLoaded", (event) => { } function closeExistingAndOpenBar(type: string, typeData: any) { - let barPage = "notification/bar.html"; - switch (type) { - case "add": - barPage = barPage + "?add=1&isVaultLocked=" + typeData.isVaultLocked; - break; - case "change": - barPage = barPage + "?change=1&isVaultLocked=" + typeData.isVaultLocked; - break; - default: - break; - } + const barQueryParams = { + type, + isVaultLocked: typeData.isVaultLocked, + theme: typeData.theme, + }; + const barQueryString = new URLSearchParams(barQueryParams).toString(); + const barPage = "notification/bar.html?" + barQueryString; const frame = document.getElementById("bit-notification-bar-iframe") as HTMLIFrameElement; if (frame != null && frame.src.indexOf(barPage) >= 0) { diff --git a/apps/browser/src/images/close.png b/apps/browser/src/images/close.png deleted file mode 100644 index ccbb3b1d5c7..00000000000 Binary files a/apps/browser/src/images/close.png and /dev/null differ diff --git a/apps/browser/src/images/close.svg b/apps/browser/src/images/close.svg new file mode 100644 index 00000000000..62c70015269 --- /dev/null +++ b/apps/browser/src/images/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index ef236acac30..3730ac6c56f 100644 --- a/apps/browser/src/manifest.json +++ b/apps/browser/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2022.10.1", + "version": "2022.10.2", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", @@ -100,8 +100,7 @@ "web_accessible_resources": [ "notification/bar.html", "images/icon38.png", - "images/icon38_locked.png", - "images/close.png" + "images/icon38_locked.png" ], "applications": { "gecko": { diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json index 5a2c2963d73..bbba272c19b 100644 --- a/apps/browser/src/manifest.v3.json +++ b/apps/browser/src/manifest.v3.json @@ -3,7 +3,7 @@ "minimum_chrome_version": "102.0", "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2022.10.1", + "version": "2022.10.2", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", @@ -106,12 +106,7 @@ }, "web_accessible_resources": [ { - "resources": [ - "notification/bar.html", - "images/icon38.png", - "images/icon38_locked.png", - "images/close.png" - ], + "resources": ["notification/bar.html", "images/icon38.png", "images/icon38_locked.png"], "matches": [""] } ], diff --git a/apps/browser/src/notification/bar.html b/apps/browser/src/notification/bar.html index 101b555df0b..6f5b111f040 100644 --- a/apps/browser/src/notification/bar.html +++ b/apps/browser/src/notification/bar.html @@ -15,7 +15,16 @@
diff --git a/apps/browser/src/notification/bar.js b/apps/browser/src/notification/bar.js index 1c1021ad5f9..316b817c36c 100644 --- a/apps/browser/src/notification/bar.js +++ b/apps/browser/src/notification/bar.js @@ -2,6 +2,9 @@ require("./bar.scss"); document.addEventListener("DOMContentLoaded", () => { + const theme = getQueryVariable("theme"); + document.documentElement.classList.add("theme_" + theme); + let i18n = {}; let lang = window.navigator.language; @@ -39,10 +42,6 @@ document.addEventListener("DOMContentLoaded", () => { var changeButton = document.querySelector("#template-change .change-save"); changeButton.textContent = i18n.notificationChangeSave; - var closeIcon = document.getElementById("close"); - closeIcon.src = chrome.runtime.getURL("images/close.png"); - closeIcon.alt = i18n.close; - var closeButton = document.getElementById("close-button"); closeButton.title = i18n.close; closeButton.setAttribute("aria-label", i18n.close); @@ -51,54 +50,10 @@ document.addEventListener("DOMContentLoaded", () => { document.querySelector("#template-change .change-text").textContent = i18n.notificationChangeDesc; - if (getQueryVariable("add")) { - setContent(document.getElementById("template-add")); - - var addButton = document.querySelector("#template-add-clone .add-save"), // eslint-disable-line - neverButton = document.querySelector("#template-add-clone .never-save"); // eslint-disable-line - - addButton.addEventListener("click", (e) => { - e.preventDefault(); - - const folderId = document.querySelector("#template-add-clone .select-folder").value; - - const bgAddSaveMessage = { - command: "bgAddSave", - folder: folderId, - }; - sendPlatformMessage(bgAddSaveMessage); - }); - - neverButton.addEventListener("click", (e) => { - e.preventDefault(); - sendPlatformMessage({ - command: "bgNeverSave", - }); - }); - - if (!isVaultLocked) { - const responseFoldersCommand = "notificationBarGetFoldersList"; - chrome.runtime.onMessage.addListener((msg) => { - if (msg.command === responseFoldersCommand && msg.data) { - fillSelectorWithFolders(msg.data.folders); - } - }); - sendPlatformMessage({ - command: "bgGetDataForTab", - responseCommand: responseFoldersCommand, - }); - } - } else if (getQueryVariable("change")) { - setContent(document.getElementById("template-change")); - var changeButton = document.querySelector("#template-change-clone .change-save"); // eslint-disable-line - changeButton.addEventListener("click", (e) => { - e.preventDefault(); - - const bgChangeSaveMessage = { - command: "bgChangeSave", - }; - sendPlatformMessage(bgChangeSaveMessage); - }); + if (getQueryVariable("type") === "add") { + handleTypeAdd(isVaultLocked); + } else if (getQueryVariable("type") === "change") { + handleTypeChange(); } closeButton.addEventListener("click", (e) => { @@ -126,6 +81,58 @@ document.addEventListener("DOMContentLoaded", () => { return null; } + function handleTypeAdd(isVaultLocked) { + setContent(document.getElementById("template-add")); + + var addButton = document.querySelector("#template-add-clone .add-save"), // eslint-disable-line + neverButton = document.querySelector("#template-add-clone .never-save"); // eslint-disable-line + + addButton.addEventListener("click", (e) => { + e.preventDefault(); + + const folderId = document.querySelector("#template-add-clone .select-folder").value; + + const bgAddSaveMessage = { + command: "bgAddSave", + folder: folderId, + }; + sendPlatformMessage(bgAddSaveMessage); + }); + + neverButton.addEventListener("click", (e) => { + e.preventDefault(); + sendPlatformMessage({ + command: "bgNeverSave", + }); + }); + + if (!isVaultLocked) { + const responseFoldersCommand = "notificationBarGetFoldersList"; + chrome.runtime.onMessage.addListener((msg) => { + if (msg.command === responseFoldersCommand && msg.data) { + fillSelectorWithFolders(msg.data.folders); + } + }); + sendPlatformMessage({ + command: "bgGetDataForTab", + responseCommand: responseFoldersCommand, + }); + } + } + + function handleTypeChange() { + setContent(document.getElementById("template-change")); + var changeButton = document.querySelector("#template-change-clone .change-save"); // eslint-disable-line + changeButton.addEventListener("click", (e) => { + e.preventDefault(); + + const bgChangeSaveMessage = { + command: "bgChangeSave", + }; + sendPlatformMessage(bgChangeSaveMessage); + }); + } + function setContent(element) { const content = document.getElementById("content"); while (content.firstChild) { diff --git a/apps/browser/src/notification/bar.scss b/apps/browser/src/notification/bar.scss index 415bfee3f75..581b34f3766 100644 --- a/apps/browser/src/notification/bar.scss +++ b/apps/browser/src/notification/bar.scss @@ -1,22 +1,31 @@ -body { - background-color: #ffffff; +@import "variables.scss"; + +body { padding: 0; margin: 0; height: 100%; font-size: 14px; line-height: 16px; - color: #333333; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-family: $font-family-sans-serif; + + @include themify($themes) { + color: themed("textColor"); + background-color: themed("backgroundColor"); + } } .outer-wrapper { padding: 0 10px; - border-bottom: 2px solid #175ddc; + border-bottom: 2px solid transparent; display: grid; grid-template-columns: 24px auto 55px; grid-column-gap: 10px; box-sizing: border-box; min-height: 42px; + + @include themify($themes) { + border-bottom-color: themed("primaryColor"); + } } .inner-wrapper { @@ -41,42 +50,86 @@ img { display: block; } -#close { - width: 15px; - height: 15px; - display: block; - padding: 5px 0; +#close-button { margin-right: 10px; } -button:not(.link), -button:not(.neutral) { - background-color: #175ddc; - padding: 5px 15px; - border-radius: 3px; - color: #ffffff; - border: 0; +#close { + display: block; + width: 17px; + height: 17px; + + > path { + @include themify($themes) { + fill: themed("textColor"); + } + } +} + +#close-button:hover { + @include themify($themes) { + border-color: rgba(themed("textColor"), 0.2); + background-color: rgba(themed("textColor"), 0.2); + } +} + +button { + padding: 0.35rem 15px; + border-radius: $border-radius; + border: 1px solid transparent; + cursor: pointer; +} + +button:not(.neutral):not(.link) { + @include themify($themes) { + background-color: themed("primaryColor"); + color: themed("textContrast"); + border-color: themed("primaryColor"); + } &:hover { - cursor: pointer; - background-color: #1751bd; + @include themify($themes) { + background-color: darken(themed("primaryColor"), 1.5%); + color: darken(themed("textContrast"), 6%); + } } } button.link, button.neutral { - background: none; - padding: 5px 15px; - color: #175ddc; - border: 0; + @include themify($themes) { + background-color: transparent; + color: themed("primaryColor"); + } &:hover { - cursor: pointer; - background: none; text-decoration: underline; + + @include themify($themes) { + background-color: transparent; + color: darken(themed("primaryColor"), 6%); + } } } +select { + padding: 0.35rem; + border: 1px solid #000000; + border-radius: $border-radius; + + @include themify($themes) { + color: themed("textColor"); + background-color: themed("inputBackgroundColor"); + border-color: themed("inputBorderColor"); + } +} + +select, +button { + font-size: $font-size-base; + font-family: $font-family-sans-serif; +} + .select-folder[isVaultLocked="true"] { display: none; } diff --git a/apps/browser/src/notification/variables.scss b/apps/browser/src/notification/variables.scss new file mode 100644 index 00000000000..ced15691997 --- /dev/null +++ b/apps/browser/src/notification/variables.scss @@ -0,0 +1,80 @@ +@import "~nord/src/sass/nord.scss"; + +$font-family-sans-serif: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +$font-size-base: 14px; +$text-color: #333333; +$border-color-dark: #ddd; +$border-radius: 3px; + +$brand-primary: #175ddc; + +$background-color: #f0f0f0; + +$solarizedDarkBase03: #002b36; +$solarizedDarkBase02: #073642; +$solarizedDarkBase01: #586e75; +$solarizedDarkBase2: #eee8d5; +$solarizedDarkCyan: #2aa198; +$solarizedDarkGreen: #859900; + +$themes: ( + light: ( + textColor: $text-color, + backgroundColor: $background-color, + primaryColor: $brand-primary, + buttonPrimaryColor: $brand-primary, + textContrast: $background-color, + inputBorderColor: darken($border-color-dark, 7%), + inputBackgroundColor: #ffffff, + ), + dark: ( + textColor: #ffffff, + backgroundColor: #2f343d, + buttonPrimaryColor: #6f9df1, + primaryColor: #6f9df1, + textContrast: #2f343d, + inputBorderColor: #4c525f, + inputBackgroundColor: #2f343d, + ), + nord: ( + textColor: $nord5, + backgroundColor: $nord1, + buttonPrimaryColor: $nord8, + primaryColor: $nord9, + textContrast: $nord2, + inputBorderColor: $nord0, + inputBackgroundColor: $nord2, + ), + solarizedDark: ( + textColor: $solarizedDarkBase2, + backgroundColor: $solarizedDarkBase03, + buttonPrimaryColor: $solarizedDarkCyan, + primaryColor: $solarizedDarkGreen, + textContrast: $solarizedDarkBase02, + inputBorderColor: rgba($solarizedDarkBase2, 0.2), + inputBackgroundColor: $solarizedDarkBase01, + ), +); + +@mixin themify($themes: $themes) { + @each $theme, $map in $themes { + html.theme_#{$theme} & { + $theme-map: () !global; + @each $key, $submap in $map { + $value: map-get(map-get($themes, $theme), "#{$key}"); + $theme-map: map-merge( + $theme-map, + ( + $key: $value, + ) + ) !global; + } + @content; + $theme-map: null !global; + } + } +} + +@function themed($key) { + @return map-get($theme-map, $key); +} diff --git a/apps/browser/src/popup/vault/add-edit-custom-fields.component.html b/apps/browser/src/popup/vault/add-edit-custom-fields.component.html index def0af30031..8464655c20b 100644 --- a/apps/browser/src/popup/vault/add-edit-custom-fields.component.html +++ b/apps/browser/src/popup/vault/add-edit-custom-fields.component.html @@ -19,6 +19,7 @@ appStopClick (click)="removeField(f)" appA11yTitle="{{ 'remove' | i18n }}" + *ngIf="!(!cipher.edit && editMode)" > @@ -33,6 +34,7 @@ class="row-label" placeholder="{{ 'name' | i18n }}" appInputVerbatim + [readonly]="!cipher.edit && editMode" /> +
@@ -44,6 +50,7 @@ [(ngModel)]="cipher.login.username" inputmode="email" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -53,6 +60,7 @@ appStopClick appA11yTitle="{{ 'generateUsername' | i18n }}" (click)="generateUsername()" + *ngIf="!(!cipher.edit && editMode)" > @@ -69,6 +77,7 @@ [(ngModel)]="cipher.login.password" appInputVerbatim [disabled]="!cipher.viewPassword" + [readonly]="!cipher.edit && editMode" />
@@ -114,7 +123,7 @@ appStopClick appA11yTitle="{{ 'generatePassword' | i18n }}" (click)="generatePassword()" - *ngIf="cipher.viewPassword" + *ngIf="cipher.viewPassword && !(!cipher.edit && editMode)" > @@ -130,6 +139,7 @@ [(ngModel)]="cipher.login.totp" appInputVerbatim [disabled]="!cipher.viewPassword" + [readonly]="!cipher.edit && editMode" />
@@ -142,6 +152,7 @@ type="text" name="Card.CardCardholderName" [(ngModel)]="cipher.card.cardholderName" + [readonly]="!cipher.edit && editMode" />
@@ -154,6 +165,7 @@ name="Card.Number" [(ngModel)]="cipher.card.number" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -175,17 +187,39 @@
- + + + + + +
- + + + + + +
@@ -195,6 +229,7 @@ name="Card.ExpYear" [(ngModel)]="cipher.card.expYear" placeholder="{{ 'ex' | i18n }} {{ currentDate | date: 'yyyy' }}" + [readonly]="!cipher.edit && editMode" />
@@ -207,6 +242,7 @@ name="Card.Code" [(ngModel)]="cipher.card.code" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -231,11 +267,22 @@
- + + + + + +
@@ -244,6 +291,7 @@ type="text" name="Identity.FirstName" [(ngModel)]="cipher.identity.firstName" + [readonly]="!cipher.edit && editMode" />
@@ -253,6 +301,7 @@ type="text" name="Identity.MiddleName" [(ngModel)]="cipher.identity.middleName" + [readonly]="!cipher.edit && editMode" />
@@ -262,6 +311,7 @@ type="text" name="Identity.LastName" [(ngModel)]="cipher.identity.lastName" + [readonly]="!cipher.edit && editMode" />
@@ -272,6 +322,7 @@ name="Identity.Username" [(ngModel)]="cipher.identity.username" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -281,6 +332,7 @@ type="text" name="Identity.Company" [(ngModel)]="cipher.identity.company" + [readonly]="!cipher.edit && editMode" />
@@ -291,6 +343,7 @@ name="Identity.SSN" [(ngModel)]="cipher.identity.ssn" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -301,6 +354,7 @@ name="Identity.PassportNumber" [(ngModel)]="cipher.identity.passportNumber" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -311,6 +365,7 @@ name="Identity.LicenseNumber" [(ngModel)]="cipher.identity.licenseNumber" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -321,6 +376,7 @@ name="Identity.Email" [(ngModel)]="cipher.identity.email" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -330,6 +386,7 @@ type="text" name="Identity.Phone" [(ngModel)]="cipher.identity.phone" + [readonly]="!cipher.edit && editMode" />
@@ -339,6 +396,7 @@ type="text" name="Identity.Address1" [(ngModel)]="cipher.identity.address1" + [readonly]="!cipher.edit && editMode" />
@@ -348,6 +406,7 @@ type="text" name="Identity.Address2" [(ngModel)]="cipher.identity.address2" + [readonly]="!cipher.edit && editMode" />
@@ -357,6 +416,7 @@ type="text" name="Identity.Address3" [(ngModel)]="cipher.identity.address3" + [readonly]="!cipher.edit && editMode" />
@@ -366,6 +426,7 @@ type="text" name="Identity.City" [(ngModel)]="cipher.identity.city" + [readonly]="!cipher.edit && editMode" />
@@ -375,6 +436,7 @@ type="text" name="Identity.State" [(ngModel)]="cipher.identity.state" + [readonly]="!cipher.edit && editMode" />
@@ -384,6 +446,7 @@ type="text" name="Identity.PostalCode" [(ngModel)]="cipher.identity.postalCode" + [readonly]="!cipher.edit && editMode" />
@@ -393,6 +456,7 @@ type="text" name="Identity.Country" [(ngModel)]="cipher.identity.country" + [readonly]="!cipher.edit && editMode" />
@@ -484,6 +548,7 @@ appStopClick (click)="addUri()" class="box-content-row box-content-row-newmulti" + *ngIf="!(!cipher.edit && editMode)" > {{ "newUri" | i18n }} @@ -535,6 +600,7 @@ name="PasswordPrompt" [ngModel]="reprompt" (change)="repromptChanged()" + [disabled]="!cipher.edit && editMode" />
- - +
@@ -31,6 +32,7 @@ class="row-label" placeholder="{{ 'name' | i18n }}" appInputVerbatim + [readonly]="!cipher.edit && editMode" /> - - + + + + + +
- + + + + + +
@@ -184,6 +216,7 @@ name="Card.ExpYear" [(ngModel)]="cipher.card.expYear" placeholder="{{ 'ex' | i18n }} {{ currentDate | date: 'yyyy' }}" + [readonly]="!cipher.edit && editMode" />
@@ -196,6 +229,7 @@ name="Card.Code" [(ngModel)]="cipher.card.code" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -220,11 +254,22 @@
- + + + + + +
@@ -233,6 +278,7 @@ type="text" name="Identity.FirstName" [(ngModel)]="cipher.identity.firstName" + [readonly]="!cipher.edit && editMode" />
@@ -242,6 +288,7 @@ type="text" name="Identity.MiddleName" [(ngModel)]="cipher.identity.middleName" + [readonly]="!cipher.edit && editMode" />
@@ -251,6 +298,7 @@ type="text" name="Identity.LastName" [(ngModel)]="cipher.identity.lastName" + [readonly]="!cipher.edit && editMode" />
@@ -261,6 +309,7 @@ name="Identity.Username" [(ngModel)]="cipher.identity.username" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -270,6 +319,7 @@ type="text" name="Identity.Company" [(ngModel)]="cipher.identity.company" + [readonly]="!cipher.edit && editMode" />
@@ -280,6 +330,7 @@ name="Identity.SSN" [(ngModel)]="cipher.identity.ssn" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -290,6 +341,7 @@ name="Identity.PassportNumber" [(ngModel)]="cipher.identity.passportNumber" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -300,6 +352,7 @@ name="Identity.LicenseNumber" [(ngModel)]="cipher.identity.licenseNumber" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -310,6 +363,7 @@ name="Identity.Email" [(ngModel)]="cipher.identity.email" appInputVerbatim + [readonly]="!cipher.edit && editMode" />
@@ -319,6 +373,7 @@ type="text" name="Identity.Phone" [(ngModel)]="cipher.identity.phone" + [readonly]="!cipher.edit && editMode" />
@@ -328,6 +383,7 @@ type="text" name="Identity.Address1" [(ngModel)]="cipher.identity.address1" + [readonly]="!cipher.edit && editMode" />
@@ -337,6 +393,7 @@ type="text" name="Identity.Address2" [(ngModel)]="cipher.identity.address2" + [readonly]="!cipher.edit && editMode" />
@@ -346,6 +403,7 @@ type="text" name="Identity.Address3" [(ngModel)]="cipher.identity.address3" + [readonly]="!cipher.edit && editMode" />
@@ -355,6 +413,7 @@ type="text" name="Identity.City" [(ngModel)]="cipher.identity.city" + [readonly]="!cipher.edit && editMode" />
@@ -364,6 +423,7 @@ type="text" name="Identity.State" [(ngModel)]="cipher.identity.state" + [readonly]="!cipher.edit && editMode" />
@@ -373,6 +433,7 @@ type="text" name="Identity.PostalCode" [(ngModel)]="cipher.identity.postalCode" + [readonly]="!cipher.edit && editMode" />
@@ -382,6 +443,7 @@ type="text" name="Identity.Country" [(ngModel)]="cipher.identity.country" + [readonly]="!cipher.edit && editMode" />
@@ -402,6 +464,7 @@ appStopClick (click)="removeUri(u)" appA11yTitle="{{ 'remove' | i18n }}" + [disabled]="!cipher.edit && editMode" > @@ -446,7 +509,13 @@
- @@ -481,6 +550,7 @@ name="PasswordPrompt" [ngModel]="reprompt" (change)="repromptChanged()" + [disabled]="!cipher.edit && editMode" /> -
+

{{ title }}

diff --git a/apps/web/src/app/send/send.component.html b/apps/web/src/app/send/send.component.html index a5460a7dfae..b0ccca88dc4 100644 --- a/apps/web/src/app/send/send.component.html +++ b/apps/web/src/app/send/send.component.html @@ -179,7 +179,7 @@ {{ "loading" | i18n }} - +

{{ "noSendsInList" | i18n }}

{{ "faviconDesc" | i18n }}
-
-
- - - - - -
- {{ "enableGravatarsDesc" | i18n }} -
- - +

diff --git a/apps/web/src/app/shared/shared.module.ts b/apps/web/src/app/shared/shared.module.ts index 7e3d96c68d0..c217b9b12e5 100644 --- a/apps/web/src/app/shared/shared.module.ts +++ b/apps/web/src/app/shared/shared.module.ts @@ -8,6 +8,7 @@ import { ToastrModule } from "ngx-toastr"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { + AsyncActionsModule, AvatarModule, BadgeModule, ButtonModule, @@ -15,7 +16,6 @@ import { FormFieldModule, IconButtonModule, IconModule, - AsyncActionsModule, MenuModule, TableModule, TabsModule, diff --git a/apps/web/src/app/vault/add-edit-custom-fields.component.html b/apps/web/src/app/vault/add-edit-custom-fields.component.html index 3d02f2d3b82..c524f346414 100644 --- a/apps/web/src/app/vault/add-edit-custom-fields.component.html +++ b/apps/web/src/app/vault/add-edit-custom-fields.component.html @@ -29,6 +29,7 @@ class="form-control" appInputVerbatim [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />

@@ -44,6 +45,7 @@ [(ngModel)]="f.value" appInputVerbatim [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" attr.aria-describedby="fieldName{{ i }}" />
@@ -68,6 +70,7 @@ appInputVerbatim autocomplete="new-password" [disabled]="cipher.isDeleted || viewOnly || (!cipher.viewPassword && !f.newField)" + [readonly]="!cipher.edit && editMode" attr.aria-describedby="fieldName{{ i }}" />
@@ -130,7 +133,7 @@ class="btn btn-link text-danger ml-2" (click)="removeField(f)" appA11yTitle="{{ 'remove' | i18n }}" - *ngIf="!cipher.isDeleted && !viewOnly" + *ngIf="!cipher.isDeleted && !viewOnly && !(!cipher.edit && editMode)" > @@ -138,7 +141,7 @@ type="button" class="btn btn-link text-muted cursor-move" appA11yTitle="{{ 'dragToSort' | i18n }}" - *ngIf="!cipher.isDeleted && !viewOnly" + *ngIf="!cipher.isDeleted && !viewOnly && !(!cipher.edit && editMode)" > @@ -152,11 +155,11 @@ appStopClick (click)="addField()" class="d-inline-block mb-2" - *ngIf="!cipher.isDeleted && !viewOnly" + *ngIf="!cipher.isDeleted && !viewOnly && !(!cipher.edit && editMode)" > {{ "newCustomField" | i18n }} -
+
- - + + + + + +
@@ -403,6 +422,7 @@ appInputVerbatim autocomplete="new-password" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -471,6 +504,7 @@ appInputVerbatim autocomplete="new-password" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -526,6 +572,7 @@ name="Identity.FirstName" [(ngModel)]="cipher.identity.firstName" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -537,6 +584,7 @@ name="Identity.MiddleName" [(ngModel)]="cipher.identity.middleName" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -548,6 +596,7 @@ name="Identity.LastName" [(ngModel)]="cipher.identity.lastName" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -562,6 +611,7 @@ [(ngModel)]="cipher.identity.username" appInputVerbatim [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -573,6 +623,7 @@ name="Identity.Company" [(ngModel)]="cipher.identity.company" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -587,6 +638,7 @@ [(ngModel)]="cipher.identity.ssn" appInputVerbatim [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -599,6 +651,7 @@ [(ngModel)]="cipher.identity.passportNumber" appInputVerbatim [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -611,6 +664,7 @@ [(ngModel)]="cipher.identity.licenseNumber" appInputVerbatim [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -626,6 +680,7 @@ [(ngModel)]="cipher.identity.email" appInputVerbatim [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -638,6 +693,7 @@ name="Identity.Phone" [(ngModel)]="cipher.identity.phone" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -651,6 +707,7 @@ name="Identity.Address1" [(ngModel)]="cipher.identity.address1" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -662,6 +719,7 @@ name="Identity.Address2" [(ngModel)]="cipher.identity.address2" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -675,6 +733,7 @@ name="Identity.Address3" [(ngModel)]="cipher.identity.address3" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -686,6 +745,7 @@ name="Identity.City" [(ngModel)]="cipher.identity.city" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -699,6 +759,7 @@ name="Identity.State" [(ngModel)]="cipher.identity.state" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -710,6 +771,7 @@ name="Identity.PostalCode" [(ngModel)]="cipher.identity.postalCode" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" />
@@ -723,6 +785,7 @@ name="Identity.Country" [(ngModel)]="cipher.identity.country" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" /> @@ -735,14 +798,17 @@ rows="6" [(ngModel)]="cipher.notes" [disabled]="cipher.isDeleted || viewOnly" + [readonly]="!cipher.edit && editMode" class="form-control" >

{{ "ownership" | i18n }}

@@ -819,7 +885,7 @@ (change)="repromptChanged()" id="passwordPrompt" name="passwordPrompt" - [disabled]="cipher.isDeleted || viewOnly" + [disabled]="cipher.isDeleted || viewOnly || (!cipher.edit && editMode)" />
- +

{{ "noItemsInList" | i18n }}