1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-04-09 19:17:09 +02:00

Merge branch 'master' into feature/flexible-collections

This commit is contained in:
Thomas Rittson 2023-09-19 13:18:45 +10:00 committed by GitHub
commit ef2b8506c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 347 additions and 214 deletions

View File

@ -37,7 +37,7 @@ jobs:
run: npm run build-storybook:ci
- name: Publish to Chromatic
uses: chromaui/action@44caff7e88d584b04f79f04e31e819f9a95d4d8f
uses: chromaui/action@a45a922b9a7522a4cbb59a7bb7b288a768968924
with:
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}

View File

@ -1,5 +1,6 @@
---
name: Version Bump
run-name: Version Bump - ${{ github.ref_name }}
on:
workflow_dispatch:
@ -96,6 +97,26 @@ jobs:
########################
### Browser
- name: Browser - Verify input version
if: ${{ inputs.bump_browser == true }}
env:
NEW_VERSION: ${{ inputs.version_number }}
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
fi
working-directory: apps/browser
- name: Bump Browser Version
if: ${{ inputs.bump_browser == true }}
env:
@ -124,6 +145,26 @@ jobs:
prettier --write apps/browser/src/manifest.v3.json
### CLI
- name: CLI - Verify input version
if: ${{ inputs.bump_cli == true }}
env:
NEW_VERSION: ${{ inputs.version_number }}
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
fi
working-directory: apps/cli
- name: Bump CLI Version
if: ${{ inputs.bump_cli == true }}
env:
@ -131,6 +172,26 @@ jobs:
run: npm version --workspace=@bitwarden/cli ${VERSION}
### Desktop
- name: Desktop - Verify input version
if: ${{ inputs.bump_desktop == true }}
env:
NEW_VERSION: ${{ inputs.version_number }}
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
fi
working-directory: apps/desktop
- name: Bump Desktop Version - Root
if: ${{ inputs.bump_desktop == true }}
env:
@ -145,6 +206,26 @@ jobs:
working-directory: "apps/desktop/src"
### Web
- name: Web - Verify input version
if: ${{ inputs.bump_web == true }}
env:
NEW_VERSION: ${{ inputs.version_number }}
run: |
CURRENT_VERSION=$(cat package.json | jq -r '.version')
# Error if version has not changed.
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
echo "Version has not changed."
exit 1
fi
# Check if version is newer.
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful."
fi
working-directory: apps/web
- name: Bump Web Version
if: ${{ inputs.bump_web == true }}
env:
@ -176,13 +257,13 @@ jobs:
run: git commit -m "Bumped ${CLIENT} version to ${VERSION}" -a
- name: Push changes
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
if: ${{ (github.ref == 'refs/heads/master') && (steps.version-changed.outputs.changes_to_commit == 'TRUE') }}
env:
BRANCH: ${{ steps.branch.outputs.branch }}
run: git push -u origin ${BRANCH}
- name: Create Bump Version PR
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
if: ${{ (github.ref == 'refs/heads/master') && (steps.version-changed.outputs.changes_to_commit == 'TRUE') }}
env:
BASE_BRANCH: master
BRANCH: ${{ steps.branch.outputs.branch }}

View File

@ -1992,7 +1992,7 @@
"message": "Şəxsi anbarın ixracı"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Yalnız $EMAIL$ ilə əlaqələndirilmiş fərdi anbar elementləri xaricə köçürüləcək. Təşkilat anbar elementləri daxil edilməyəcək. Yalnız anbar element məlumatları xaricə köçürüləcək və əlaqələndirilmiş qoşmalar daxil edilməyəcək.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "S'està exportant la caixa forta personal"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Només s'exportaran els elements de la caixa forta individuals associats a $EMAIL$. Els elements de la caixa de l'organització no s'inclouran. Només s'exportarà la informació de l'element de la caixa forta i no inclourà els fitxers adjunts associats.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Exportování osobního trezoru"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Budou exportovány jen osobní položky trezoru spojené s $EMAIL$. Položky trezoru organizace nebudou zahrnuty. Budou exportovány jen informace o položkách trezoru a nebudou zahrnuty související přílohy.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Eksporterer personlig boks"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Kun individuelle Boksemner tilknyttet $EMAIL$ eksporteres. Organisationsboksemner medtages ikke. Kun Boksemneinformation uden tilhørende vedhæftninger eksporteres.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Persönlicher Tresor wird exportiert"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Es werden nur persönliche Tresoreinträge exportiert, die mit $EMAIL$ verbunden sind. Tresoreinträge der Organisation werden nicht berücksichtigt. Es werden nur Informationen der Tresoreinträge exportiert. Diese enthalten nicht die zugehörigen Anhänge.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -44,7 +44,7 @@
"message": "Η υπόδειξη του κύριου κωδικού μπορεί να σας βοηθήσει να θυμηθείτε τον κωδικό σας, σε περίπτωση που τον ξεχάσετε."
},
"reTypeMasterPass": {
"message": "Εισάγετε Ξανά τον Κύριο Κωδικό σας"
"message": "Εισάγετε ξανά τον Κύριο Κωδικό"
},
"masterPassHint": {
"message": "Υπόδειξη Κύριου Κωδικού (προαιρετικό)"
@ -997,7 +997,7 @@
"message": "Μπορείτε να απενεργοποιήσετε την αυτόματη συμπλήρωση φόρτωσης σελίδας για μεμονωμένα στοιχεία σύνδεσης από την προβολή Επεξεργασία στοιχείου."
},
"itemAutoFillOnPageLoad": {
"message": "Αυτόματη συμπλήρωση της Φόρτισης Σελίδας (αν είναι ενεργοποιημένη στις Επιλογές)"
"message": "Αυτόματη συμπλήρωση κατά τη φόρτωση της σελίδας (αν έχει ενεργοποιηθεί στις Ρυθμίσεις)"
},
"autoFillOnPageLoadUseDefault": {
"message": "Χρήση προεπιλεγμένης ρύθμισης"

View File

@ -1992,7 +1992,7 @@
"message": "Exporting individual vault"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organisation vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Personaalse hoidla eksportimine"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Ainult e-postiga $EMAIL$ seonduvad kirjed eksporditakse. Organisatsiooni kirjeid ei kaasata. Samuti ei kaasata organisatsiooniga seonduvaid manuseid.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Henkilökohtaisen holvin vienti"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Vain tunnukseen $EMAIL$ liitetyt yksityisen holvin kohteet viedään. Organisaation holvin kohteita ei sisällytetä. Vain holvin kohteiden tiedot viedään ilman niiden sisältämiä liitteitä.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Exporting individual vault"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "केवल $EMAIL$ से संबद्ध, व्यक्तिगत वॉल्ट वस्तुएँ निर्यात की जाएंगी. संगठन वॉल्ट वस्तुएँ शामिल नहीं की जाएंगी. केवल वॉल्ट वस्तुओं की जानकारी निर्यात की जाएगी और इसमें संबंधित अनुलग्नक शामिल नहीं होंगे.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "個人保管庫のエクスポート"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "$EMAIL$ に関連付けられた個人の保管庫アイテムのみがエクスポートされます。組織の保管庫アイテムは含まれません。 保管庫アイテム情報のみがエクスポートされ、関連する添付ファイルはエクスポートされません。",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Izdod personīgo glabātavu"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Tiks izgūti tikai atsevišķi glabātavas vienumi, kas ir saistīti ar $EMAIL$. Apvienības glabātavas vienumi netiks iekļauti. Tiks izgūta tikai glabātavas vienumu informācija, un saistītie pielikumi netiks iekļauti.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Экспорт личного хранилища"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Будут экспортированы только отдельные элементы хранилища, связанные с $EMAIL$. Элементы хранилища организации включены не будут. Экспортируется только информация об элементах хранилища, не включая связанные вложения.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Извоз личног сефа"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Само појединачне ставке сефа повезане са $EMAIL$ ће бити извењене. Ставке организационог сефа неће бити укључене. Само информације о ставкама из сефа ће бити извезене и неће укључивати повезане прилоге.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Kişisel kasa dışa aktarılıyor"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Yalnızca $EMAIL$ ile ilişkili kasa kayıtları dışa aktarılacaktır. Kuruluş kasasındaki kayıtlar dahil edilmeyecektir. Yalnızca kasa kayıt bilgileri dışa aktarılacak, kayıtlara eklenen dosyalar aktarılmayacaktır.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1992,7 +1992,7 @@
"message": "Експортування особистого сховища"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Будуть експортовані лише записи особистого сховища, пов'язані з $EMAIL$. Записи сховища організації не буде включено. Експортуються лише дані записів сховища без пов'язаних вкладень.",
"placeholders": {
"email": {
"content": "$1",
@ -2093,7 +2093,7 @@
"message": "Версія сервера"
},
"selfHostedServer": {
"message": "self-hosted"
"message": "власне розміщення"
},
"thirdParty": {
"message": "Сторонній"

View File

@ -751,7 +751,7 @@
"message": "附件已删除"
},
"newAttachment": {
"message": "添加新附件"
"message": "添加新附件"
},
"noAttachments": {
"message": "没有附件。"
@ -853,7 +853,7 @@
"message": "请输入您的验证器应用中的 6 位验证码。"
},
"enterVerificationCodeEmail": {
"message": "请输入通过电子邮件发送给 $EMAIL$ 的 6 位验证码。",
"message": "请输入发送给电子邮件 $EMAIL$ 的 6 位数验证码。",
"placeholders": {
"email": {
"content": "$1",
@ -1036,7 +1036,7 @@
"message": "值"
},
"newCustomField": {
"message": "新自定义字段"
"message": "新自定义字段"
},
"dragToSort": {
"message": "拖动排序"
@ -1059,7 +1059,7 @@
"description": "This describes a value that is 'linked' (tied) to another value."
},
"popup2faCloseMessage": {
"message": "如果您点击弹窗外的任何区域,将导致弹窗关闭。您想在新窗口中打开此弹窗,以便它不会关闭吗?"
"message": "如果您点击弹窗外的区域以检查您的验证码电子邮件,将导致弹窗关闭。您想在新窗口中打开此弹窗,以便它不会关闭吗?"
},
"popupU2fCloseMessage": {
"message": "此浏览器无法处理此弹出窗口中的 U2F 请求。您想要在新窗口中打开此弹出窗口吗?"
@ -1182,7 +1182,7 @@
"message": "许可证号码"
},
"email": {
"message": "Email"
"message": "电子邮件"
},
"phone": {
"message": "电话"
@ -1615,7 +1615,7 @@
"message": "未提供权限"
},
"nativeMessaginPermissionErrorDesc": {
"message": "没有与 Bitwarden 桌面应用程序通信的权限,我们无法在浏览器扩展中提供生物识别。请再试一次。"
"message": "没有与 Bitwarden 桌面应用程序通信的权限,我们无法在浏览器扩展中提供生物识别。请重试。"
},
"nativeMessaginPermissionSidebarTitle": {
"message": "权限请求错误"
@ -1896,7 +1896,7 @@
"message": "选择文件夹..."
},
"ssoCompleteRegistration": {
"message": "要完成 SSO 登配置,请设置一个主密码以访问和保护您的密码库。"
"message": "要完成 SSO 登配置,请设置一个主密码以访问和保护您的密码库。"
},
"hours": {
"message": "小时"
@ -1986,13 +1986,13 @@
"message": "字符计数开关"
},
"sessionTimeout": {
"message": "您的会话已超时。请返回尝试重新登录。"
"message": "您的会话已超时。请返回然后尝试重新登录。"
},
"exportingPersonalVaultTitle": {
"message": "导出个人密码库"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "仅会导出与 $EMAIL$ 关联的个人密码库项目,不包括组织密码库项目。仅会导出密码库项目信息,不包括关联的附件。",
"placeholders": {
"email": {
"content": "$1",
@ -2117,7 +2117,7 @@
}
},
"loginWithMasterPassword": {
"message": "使用主密码登录"
"message": "主密码登录"
},
"loggingInAs": {
"message": "正登录为"

View File

@ -9,7 +9,7 @@
<label for="email">{{ "emailAddress" | i18n }}</label>
<input id="email" type="email" formControlName="email" appInputVerbatim="false" />
</div>
<environment-selector class="environment-selector-padding"></environment-selector>
<environment-selector></environment-selector>
<div class="remember-email-check">
<input
id="rememberEmail"

View File

@ -0,0 +1,36 @@
/**
* Monkey patch `chrome.runtime.onMessage` event listeners to run in the Angular zone.
*/
Zone.__load_patch("ChromeRuntimeOnMessage", (global: any, Zone: ZoneType, api: _ZonePrivate) => {
const onMessage = global.chrome.runtime.onMessage;
if (typeof global?.chrome?.runtime?.onMessage === "undefined") {
return;
}
// eslint-disable-next-line @typescript-eslint/ban-types
api.patchMethod(onMessage, "addListener", (delegate: Function) => (self: any, args: any[]) => {
const callback = args.length > 0 ? args[0] : null;
if (typeof callback === "function") {
const wrapperedCallback = Zone.current.wrap(callback, "ChromeRuntimeOnMessage");
callback[api.symbol("chromeRuntimeOnMessageCallback")] = wrapperedCallback;
return delegate.call(self, wrapperedCallback);
} else {
return delegate.apply(self, args);
}
});
// eslint-disable-next-line @typescript-eslint/ban-types
api.patchMethod(onMessage, "removeListener", (delegate: Function) => (self: any, args: any[]) => {
const callback = args.length > 0 ? args[0] : null;
if (typeof callback === "function") {
const wrapperedCallback = callback[api.symbol("chromeRuntimeOnMessageCallback")];
if (wrapperedCallback) {
return delegate.call(self, wrapperedCallback);
} else {
return delegate.apply(self, args);
}
} else {
return delegate.apply(self, args);
}
});
});

View File

@ -86,31 +86,25 @@ export class AppComponent implements OnInit, OnDestroy {
sendResponse: any
) => {
if (msg.command === "doneLoggingOut") {
this.ngZone.run(async () => {
this.authService.logOut(async () => {
if (msg.expired) {
this.showToast({
type: "warning",
title: this.i18nService.t("loggedOut"),
text: this.i18nService.t("loginExpired"),
});
}
this.authService.logOut(async () => {
if (msg.expired) {
this.showToast({
type: "warning",
title: this.i18nService.t("loggedOut"),
text: this.i18nService.t("loginExpired"),
});
}
if (this.activeUserId === null) {
this.router.navigate(["home"]);
}
});
this.changeDetectorRef.detectChanges();
if (this.activeUserId === null) {
this.router.navigate(["home"]);
}
});
this.changeDetectorRef.detectChanges();
} else if (msg.command === "authBlocked") {
this.ngZone.run(() => {
this.router.navigate(["home"]);
});
this.router.navigate(["home"]);
} else if (msg.command === "locked") {
if (msg.userId == null || msg.userId === (await this.stateService.getUserId())) {
this.ngZone.run(() => {
this.router.navigate(["lock"]);
});
this.router.navigate(["lock"]);
}
} else if (msg.command === "showDialog") {
await this.ngZone.run(() => this.showDialog(msg));
@ -118,9 +112,7 @@ export class AppComponent implements OnInit, OnDestroy {
// TODO: Should be refactored to live in another service.
await this.ngZone.run(() => this.showNativeMessagingFingerprintDialog(msg));
} else if (msg.command === "showToast") {
this.ngZone.run(() => {
this.showToast(msg);
});
this.showToast(msg);
} else if (msg.command === "reloadProcess") {
const forceWindowReload =
this.platformUtilsService.isSafari() ||
@ -132,13 +124,9 @@ export class AppComponent implements OnInit, OnDestroy {
2000
);
} else if (msg.command === "reloadPopup") {
this.ngZone.run(() => {
this.router.navigate(["/"]);
});
this.router.navigate(["/"]);
} else if (msg.command === "convertAccountToKeyConnector") {
this.ngZone.run(async () => {
this.router.navigate(["/remove-password"]);
});
this.router.navigate(["/remove-password"]);
} else {
msg.webExtSender = sender;
this.broadcasterService.send(msg);

View File

@ -61,7 +61,6 @@ import { PrivateModeWarningComponent } from "./components/private-mode-warning.c
import { SetPinComponent } from "./components/set-pin.component";
import { UserVerificationComponent } from "./components/user-verification.component";
import { ServicesModule } from "./services/services.module";
import { AboutComponent } from "./settings/about.component";
import { AutofillComponent } from "./settings/autofill.component";
import { ExcludedDomainsComponent } from "./settings/excluded-domains.component";
import { FoldersComponent } from "./settings/folders.component";
@ -151,7 +150,6 @@ import "../platform/popup/locales";
ViewCustomFieldsComponent,
RemovePasswordComponent,
VaultSelectComponent,
AboutComponent,
HelpAndFeedbackComponent,
AutofillComponent,
EnvironmentSelectorComponent,

View File

@ -1,3 +1,5 @@
import "core-js/stable";
import "date-input-polyfill";
import "zone.js";
import "../platform/polyfills/zone-patch-chrome-runtime";

View File

@ -6,6 +6,12 @@
margin: 0;
}
html {
&.cdk-global-scrollblock {
position: unset;
}
}
html,
body {
font-family: $font-family-sans-serif;

View File

@ -51,15 +51,11 @@ html.browser_safari {
color: $text-muted;
line-height: 25px;
font-weight: 400;
padding-left: 5px;
padding-left: 15px;
label {
span {
font-weight: 600;
}
a,
a label:hover {
cursor: pointer;
font-size: $font-size-small;
}
}
@ -91,7 +87,3 @@ html.browser_safari {
}
}
}
.environment-selector-padding {
padding-left: 10px;
}

View File

@ -1,52 +1,46 @@
<div class="modal fade" role="dialog" aria-modal="true">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document">
<div class="modal-content">
<div class="modal-body">
<p class="text-center">
<i class="bwi bwi-shield bwi-3x" aria-hidden="true"></i>
</p>
<p class="text-center">
<b>Bitwarden</b>
</p>
<p class="text-center">&copy; Bitwarden Inc. 2015-{{ year }}</p>
<p class="text-center">{{ "version" | i18n }}: {{ version }}</p>
<ng-container *ngIf="serverConfig$ | async as serverConfig">
<p class="text-center" *ngIf="isCloud">
{{ "serverVersion" | i18n }}: {{ this.serverConfig?.version }}
<bit-simple-dialog>
<div bitDialogIcon>
<i class="bwi bwi-shield bwi-3x" aria-hidden="true"></i>
</div>
<div bitDialogTitle>Bitwarden</div>
<div bitDialogContent>
<p>&copy; Bitwarden Inc. 2015-{{ year }}</p>
<p>{{ "version" | i18n }}: {{ version }}</p>
<ng-container *ngIf="serverConfig$ | async as serverConfig">
<p *ngIf="isCloud">
{{ "serverVersion" | i18n }}: {{ this.serverConfig?.version }}
<span *ngIf="!serverConfig.isValid()">
({{ "lastSeenOn" | i18n : (serverConfig.utcDate | date : "mediumDate") }})
</span>
</p>
<ng-container *ngIf="!isCloud">
<ng-container *ngIf="serverConfig.server">
<p>
{{ "serverVersion" | i18n }} <small>({{ "thirdParty" | i18n }})</small>:
{{ this.serverConfig?.version }}
<span *ngIf="!serverConfig.isValid()">
({{ "lastSeenOn" | i18n : (serverConfig.utcDate | date : "mediumDate") }})
</span>
</p>
<ng-container *ngIf="!isCloud">
<ng-container *ngIf="serverConfig.server">
<p class="text-center">
{{ "serverVersion" | i18n }} <small>({{ "thirdParty" | i18n }})</small>:
{{ this.serverConfig?.version }}
<span *ngIf="!serverConfig.isValid()">
({{ "lastSeenOn" | i18n : (serverConfig.utcDate | date : "mediumDate") }})
</span>
</p>
<div class="text-center">
<small>{{ "thirdPartyServerMessage" | i18n : serverConfig.server?.name }}</small>
</div>
</ng-container>
<p class="text-center" *ngIf="!serverConfig.server">
{{ "serverVersion" | i18n }} <small>({{ "selfHostedServer" | i18n }})</small>:
{{ this.serverConfig?.version }}
<span *ngIf="!serverConfig.isValid()">
({{ "lastSeenOn" | i18n : (serverConfig.utcDate | date : "mediumDate") }})
</span>
</p>
</ng-container>
<div>
<small>{{ "thirdPartyServerMessage" | i18n : serverConfig.server?.name }}</small>
</div>
</ng-container>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">
{{ "close" | i18n }}
</button>
</div>
</div>
<p *ngIf="!serverConfig.server">
{{ "serverVersion" | i18n }} <small>({{ "selfHostedServer" | i18n }})</small>:
{{ this.serverConfig?.version }}
<span *ngIf="!serverConfig.isValid()">
({{ "lastSeenOn" | i18n : (serverConfig.utcDate | date : "mediumDate") }})
</span>
</p>
</ng-container>
</ng-container>
</div>
</div>
<div bitDialogFooter>
<button bitButton bitDialogClose buttonType="primary" type="button">
{{ "close" | i18n }}
</button>
</div>
</bit-simple-dialog>

View File

@ -1,25 +1,29 @@
import { CommonModule } from "@angular/common";
import { Component } from "@angular/core";
import { Observable } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
import { ServerConfig } from "@bitwarden/common/platform/abstractions/config/server-config";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { ButtonModule, DialogModule } from "@bitwarden/components";
import { BrowserApi } from "../../platform/browser/browser-api";
@Component({
selector: "app-about",
templateUrl: "about.component.html",
standalone: true,
imports: [CommonModule, JslibModule, DialogModule, ButtonModule],
})
export class AboutComponent {
serverConfig$: Observable<ServerConfig>;
protected serverConfig$: Observable<ServerConfig> = this.configService.serverConfig$;
year = new Date().getFullYear();
version = BrowserApi.getApplicationVersion();
isCloud: boolean;
protected year = new Date().getFullYear();
protected version = BrowserApi.getApplicationVersion();
protected isCloud = this.environmentService.isCloud();
constructor(configService: ConfigServiceAbstraction, environmentService: EnvironmentService) {
this.serverConfig$ = configService.serverConfig$;
this.isCloud = environmentService.isCloud();
}
constructor(
private configService: ConfigServiceAbstraction,
private environmentService: EnvironmentService
) {}
}

View File

@ -482,7 +482,7 @@ export class SettingsComponent implements OnInit {
}
about() {
this.modalService.open(AboutComponent);
this.dialogService.open(AboutComponent);
}
async fingerprint() {

View File

@ -1,7 +1,7 @@
{
"name": "@bitwarden/desktop",
"description": "A secure and free password manager for all of your devices.",
"version": "2023.8.4",
"version": "2023.8.5",
"keywords": [
"bitwarden",
"password",

View File

@ -1985,7 +1985,7 @@
"message": "Şəxsi anbarın ixracı"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Yalnız $EMAIL$ ilə əlaqələndirilmiş fərdi anbar elementləri xaricə köçürüləcək. Təşkilat anbar elementləri daxil edilməyəcək. Yalnız anbar element məlumatları xaricə köçürüləcək və əlaqələndirilmiş qoşmalar daxil edilməyəcək.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "S'està exportant la caixa forta personal"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Només s'exportaran els elements de la caixa forta individuals associats a $EMAIL$. Els elements de la caixa de l'organització no s'inclouran. Només s'exportarà la informació de l'element de la caixa forta i no inclourà els fitxers adjunts associats.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "Exportování osobního trezoru"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Budou exportovány jen osobní položky trezoru spojené s $EMAIL$. Položky trezoru organizace nebudou zahrnuty. Budou exportovány jen informace o položkách trezoru a nebudou zahrnuty související přílohy.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "Eksporterer individuel boks"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Kun individuelle Boksemner tilknyttet $EMAIL$ eksporteres. Organisationsboksemner medtages ikke. Kun Boksemneinformation uden tilhørende vedhæftninger eksporteres.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "Persönlichen Tresor exportieren"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Es werden nur persönliche Tresoreinträge exportiert, die mit $EMAIL$ verbunden sind. Tresoreinträge der Organisation werden nicht berücksichtigt. Es werden nur Informationen der Tresoreinträge exportiert. Diese enthalten nicht die zugehörigen Anhänge.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -929,7 +929,7 @@
"message": "Όταν ελαχιστοποιείται το παράθυρο, εμφανίζεται ένα εικονίδιο στη γραμμή μενού."
},
"enableCloseToTray": {
"message": "Κλείσιμο στο Εικονίδιο Δίσκου"
"message": "Κλείσιμο σε εικονίδιο περιοχής ειδοποιήσεων"
},
"enableCloseToTrayDesc": {
"message": "Κατά το κλείσιμο του παραθύρου, να εμφανίζεται ένα εικονίδιο στην περιοχή ειδοποιήσεων."
@ -941,13 +941,13 @@
"message": "Κατά το κλείσιμο του παραθύρου, εμφανίζεται ένα εικονίδιο στη γραμμή μενού."
},
"enableTray": {
"message": "Ενεργοποίηση Εικονιδίου Δίσκου"
"message": "Ενεργοποίηση εικονιδίου περιοχής ειδοποιήσεων"
},
"enableTrayDesc": {
"message": "Να εμφανίζεται πάντα ένα εικονίδιο στην περιοχή ειδοποιήσεων."
},
"startToTray": {
"message": "Έναρξη στο εικονίδιο δίσκου"
"message": "Έναρξη σε εικονίδιο περιοχής ειδοποιήσεων"
},
"startToTrayDesc": {
"message": "Όταν ξεκινάει για πρώτη φορά η εφαρμογή, να εμφανίζεται μόνο ένα εικονίδιο στην περιοχή ειδοποιήσεων."
@ -1408,7 +1408,7 @@
"message": "Ξεκλειδώστε το vault σας"
},
"autoPromptWindowsHello": {
"message": "Εμφάνιση Windows Hello κατά την εκκίνηση της εφαρμογής"
"message": "Να ζητείται Windows Hello κατά την εκκίνηση της εφαρμογής"
},
"autoPromptTouchId": {
"message": "Ερώτηση για το Touch ID κατά την εκκίνηση"
@ -2250,7 +2250,7 @@
"message": "Ενημέρωση Προτεινόμενων Ρυθμίσεων"
},
"deviceApprovalRequired": {
"message": "Device approval required. Select an approval option below:"
"message": "Απαιτείται έγκριση συσκευής. Επιλέξτε μια επιλογή έγκρισης παρακάτω:"
},
"rememberThisDevice": {
"message": "Remember this device"
@ -2320,7 +2320,7 @@
"message": "Input is required."
},
"required": {
"message": "required"
"message": "απαιτείται"
},
"search": {
"message": "Search"

View File

@ -1985,7 +1985,7 @@
"message": "Personaalse hoidla eksportimine"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Ainult e-postiga $EMAIL$ seonduvad kirjed eksporditakse. Organisatsiooni kirjeid ei kaasata. Samuti ei kaasata organisatsiooniga seonduvaid manuseid.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "Henkilökohtaisen holvin vienti"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Vain tunnukseen $EMAIL$ liitetyt yksityisen holvin kohteet viedään. Organisaation holvin kohteita ei sisällytetä. Vain holvin kohteiden tiedot viedään ilman niiden sisältämiä liitteitä.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "Személyes széf exportálása"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "$EMAIL$ email címhez társított egyedi széfek kerülnek csak exportálásra. A szervezeti széf elemei nem lesznek benne. Csak a széf információk kerülnek exportálásra és nem tartalmazzák a kapcsolódó mellékleteket.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "個人保管庫のエクスポート"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "$EMAIL$ に関連付けられた個人の保管庫アイテムのみがエクスポートされます。組織の保管庫アイテムは含まれません。 保管庫アイテム情報のみがエクスポートされ、関連する添付ファイルはエクスポートされません。",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "Izdod personīgo glabātavu"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Tiks izgūti tikai atsevišķi glabātavas vienumi, kas ir saistīti ar $EMAIL$. Apvienības glabātavas vienumi netiks iekļauti. Tiks izgūta tikai glabātavas vienumu informācija, un saistītie pielikumi netiks iekļauti.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "Экспорт личного хранилища"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Будут экспортированы только отдельные элементы хранилища, связанные с $EMAIL$. Элементы хранилища организации включены не будут. Экспортируется только информация об элементах хранилища, не включая связанные вложения.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "Извоз личног сефа"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Само појединачне ставке сефа повезане са $EMAIL$ ће бити извењене. Ставке организационог сефа неће бити укључене. Само информације о ставкама из сефа ће бити извезене и неће укључивати повезане прилоге.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "Kişisel kasa dışa aktarılıyor"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Yalnızca $EMAIL$ ile ilişkili kasa kayıtları dışa aktarılacaktır. Kuruluş kasasındaki kayıtlar dahil edilmeyecektir. Yalnızca kasa kayıt bilgileri dışa aktarılacak, kayıtlara eklenen dosyalar aktarılmayacaktır.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1985,7 +1985,7 @@
"message": "Експортування особистого сховища"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "Будуть експортовані лише записи особистого сховища, пов'язані з $EMAIL$. Записи сховища організації не буде включено. Експортуються лише дані записів сховища без пов'язаних вкладень.",
"placeholders": {
"email": {
"content": "$1",
@ -2287,7 +2287,7 @@
"message": "bitwarden.eu"
},
"selfHostedServer": {
"message": "self-hosted"
"message": "власне розміщення"
},
"accessDenied": {
"message": "Доступ заборонено. У вас немає дозволу на перегляд цієї сторінки."

View File

@ -317,7 +317,7 @@
"message": "文件夹"
},
"newCustomField": {
"message": "新自定义字段"
"message": "新自定义字段"
},
"value": {
"message": "值"
@ -555,7 +555,7 @@
"message": "两次填写的主密码不一致。"
},
"newAccountCreated": {
"message": "已经为您建立了账户,您可以登录了。"
"message": "您的新账户已创建!您现在可以登录了。"
},
"masterPassSent": {
"message": "我们已经为您发送了包含主密码提示的邮件。"
@ -597,7 +597,7 @@
"message": "请输入您的身份验证器应用中的 6 位验证码。"
},
"enterVerificationCodeEmail": {
"message": "请输入通过电子邮件发送给 $EMAIL$ 的 6 位验证码。",
"message": "请输入发送给电子邮件 $EMAIL$ 的 6 位数验证码。",
"placeholders": {
"email": {
"content": "$1",
@ -618,7 +618,7 @@
"message": "记住我"
},
"sendVerificationCodeEmailAgain": {
"message": "重发验证码电子邮件"
"message": "再次发送验证码电子邮件"
},
"useAnotherTwoStepMethod": {
"message": "使用其他两步登录方式"
@ -663,7 +663,7 @@
"message": "使用任何 WebAuthn 兼容的安全钥匙访问您的帐户。"
},
"emailTitle": {
"message": "电子邮件地址"
"message": "电子邮件"
},
"emailDesc": {
"message": "验证码将会发送到您的电子邮箱。"
@ -744,13 +744,13 @@
"message": "注销"
},
"addNewLogin": {
"message": "添加新登录"
"message": "登录"
},
"addNewItem": {
"message": "新增项目"
},
"addNewFolder": {
"message": "添加文件夹"
"message": "新增文件夹"
},
"view": {
"message": "查看"
@ -1414,7 +1414,7 @@
"message": "应用程序启动时要求使用触控 ID"
},
"requirePasswordOnStart": {
"message": "应用程序启动时要求输入密码或 PIN"
"message": "应用程序启动时要求输入密码或 PIN"
},
"recommendedForSecurity": {
"message": "安全起见,推荐设置。"
@ -1534,7 +1534,7 @@
"message": "设置主密码"
},
"ssoCompleteRegistration": {
"message": "要完成 SSO 登配置,请设置一个主密码以访问和保护您的密码库。"
"message": "要完成 SSO 登配置,请设置一个主密码以访问和保护您的密码库。"
},
"currentMasterPass": {
"message": "当前主密码"
@ -1979,13 +1979,13 @@
"message": "选项"
},
"sessionTimeout": {
"message": "您的会话已超时。请返回尝试重新登录。"
"message": "您的会话已超时。请返回然后尝试重新登录。"
},
"exportingPersonalVaultTitle": {
"message": "正在导出个人密码库"
},
"exportingIndividualVaultDescription": {
"message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.",
"message": "仅会导出与 $EMAIL$ 关联的个人密码库项目,不包括组织密码库项目。仅会导出密码库项目信息,不包括关联的附件。",
"placeholders": {
"email": {
"content": "$1",
@ -2083,7 +2083,7 @@
"message": "密码库"
},
"loginWithMasterPassword": {
"message": "使用主密码登录"
"message": "主密码登录"
},
"loggingInAs": {
"message": "正登录为"
@ -2244,7 +2244,7 @@
}
},
"windowsBiometricUpdateWarning": {
"message": "Bitwarden 建议更新您的生物识别设置,以在首次解锁时要求输入您的主密码(或 PIN)。现在要更新您的设置吗?"
"message": "Bitwarden 建议更新您的生物识别设置,以在首次解锁时要求输入您的主密码(或 PIN)。现在要更新您的设置吗?"
},
"windowsBiometricUpdateWarningTitle": {
"message": "推荐的设置更新"

View File

@ -2196,10 +2196,10 @@
"message": "登入要求已逾期。"
},
"thisRequestIsNoLongerValid": {
"message": "This request is no longer valid."
"message": "此請求已失效"
},
"approveLoginRequestDesc": {
"message": "Use this device to approve login requests made from other devices."
"message": "使用此裝置準予來自其他裝置的登入要求。"
},
"confirmLoginAtemptForMail": {
"message": "確認 $EMAIL$ 的登入嘗試",
@ -2259,19 +2259,19 @@
"message": "Uncheck if using a public device"
},
"approveFromYourOtherDevice": {
"message": "Approve from your other device"
"message": "從其他裝置批准"
},
"requestAdminApproval": {
"message": "Request admin approval"
"message": "要求管理員核准"
},
"approveWithMasterPassword": {
"message": "Approve with master password"
"message": "使用主密碼批准"
},
"region": {
"message": "區域"
},
"ssoIdentifierRequired": {
"message": "Organization SSO identifier is required."
"message": "需要單一登入 (SSO) 組織識別碼。"
},
"eu": {
"message": "EU",
@ -2287,7 +2287,7 @@
"message": "bitwarden.eu"
},
"selfHostedServer": {
"message": "self-hosted"
"message": "自建"
},
"accessDenied": {
"message": "拒絕存取。您沒有檢視此頁面的權限。"
@ -2314,10 +2314,10 @@
"message": "User email missing"
},
"deviceTrusted": {
"message": "Device trusted"
"message": "裝置已信任"
},
"inputRequired": {
"message": "Input is required."
"message": "必須輸入內容。"
},
"required": {
"message": "必填"

View File

@ -1,12 +1,12 @@
{
"name": "@bitwarden/desktop",
"version": "2023.8.4",
"version": "2023.8.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@bitwarden/desktop",
"version": "2023.8.4",
"version": "2023.8.5",
"license": "GPL-3.0",
"dependencies": {
"@bitwarden/desktop-native": "file:../desktop_native"

View File

@ -2,7 +2,7 @@
"name": "@bitwarden/desktop",
"productName": "Bitwarden",
"description": "A secure and free password manager for all of your devices.",
"version": "2023.8.4",
"version": "2023.8.5",
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
"homepage": "https://bitwarden.com",
"license": "GPL-3.0",

View File

@ -18,15 +18,11 @@
color: $text-muted;
line-height: 25px;
font-weight: 400;
padding-left: 5px;
padding-left: 15px;
label {
span {
font-weight: 600;
}
a,
a label:hover {
cursor: pointer;
font-size: $font-size-small;
}
}

View File

@ -5446,7 +5446,7 @@
"message": "Organisaation holvin vienti"
},
"exportingIndividualVaultDescription": {
"message": "Vain tunnukseen $EMAIL$ liitetyt yksityisen holvin kohteet viedään. Organisaation holvin kohteita ei sisällytetä. Vain holvin kohteiden tiedot viedään ilman niihin liittyviä liitteitä.",
"message": "Vain tunnukseen $EMAIL$ liitetyt yksityisen holvin kohteet viedään. Organisaation holvin kohteita ei sisällytetä. Vain holvin kohteiden tiedot viedään ilman niiden sisältämiä liitteitä.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -5446,7 +5446,7 @@
"message": "Izdod apvienības glabātavu"
},
"exportingIndividualVaultDescription": {
"message": "Tiks izgūti tikai atsevišķi glabātavas vienumi, kas ir saistīti ar $EMAIL$. Apvienīgas glabātavas vienumi netiks iekļauti. Tiks izgūta tikai glabātavas vienuma informācija, un saistītie pielikumi netiks iekļauti.",
"message": "Tiks izgūti tikai atsevišķi glabātavas vienumi, kas ir saistīti ar $EMAIL$. Apvienības glabātavas vienumi netiks iekļauti. Tiks izgūta tikai glabātavas vienumu informācija, un saistītie pielikumi netiks iekļauti.",
"placeholders": {
"email": {
"content": "$1",

View File

@ -1426,10 +1426,10 @@
"message": "Захистіть обліковий запис, вимагаючи додатковий крок перевірки під час входу."
},
"twoStepLoginTeamsDesc": {
"message": "Enable two-step login for your organization."
"message": "Увімкніть двоетапну перевірку для вашої організації."
},
"twoStepLoginEnterpriseDescStart": {
"message": "Enforce Bitwarden Two-step Login options for members by using the ",
"message": "Зобов'язувати учасників використовувати двоетапну перевірку Bitwarden за допомогою ",
"description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Enforce Bitwarden Two-step Login options for members by using the Two-step Login Policy.'"
},
"twoStepLoginPolicy": {

View File

@ -1,40 +1,51 @@
<label class="environment-selector-btn">
<div class="environment-selector-btn">
{{ "loggingInOn" | i18n }}:
<a
<button
type="button"
(click)="toggle(null)"
cdkOverlayOrigin
#trigger="cdkOverlayOrigin"
aria-haspopup="menu"
aria-haspopup="dialog"
aria-controls="cdk-overlay-container"
[ngSwitch]="selectedEnvironment"
>
<label *ngSwitchCase="ServerEnvironmentType.US" class="text-primary">{{
<span *ngSwitchCase="ServerEnvironmentType.US" class="text-primary">{{
"usDomain" | i18n
}}</label>
<label *ngSwitchCase="ServerEnvironmentType.EU" class="text-primary">{{
}}</span>
<span *ngSwitchCase="ServerEnvironmentType.EU" class="text-primary">{{
"euDomain" | i18n
}}</label>
<label *ngSwitchCase="ServerEnvironmentType.SelfHosted" class="text-primary">{{
}}</span>
<span *ngSwitchCase="ServerEnvironmentType.SelfHosted" class="text-primary">{{
"selfHostedServer" | i18n
}}</label>
}}</span>
<i class="bwi bwi-fw bwi-sm bwi-angle-down" aria-hidden="true"></i>
</a>
</label>
</button>
</div>
<ng-template
cdkConnectedOverlay
[cdkConnectedOverlayOrigin]="trigger"
(backdropClick)="close()"
(detach)="close()"
[cdkConnectedOverlayOpen]="isOpen"
[cdkConnectedOverlayPositions]="overlayPosition"
[cdkConnectedOverlayHasBackdrop]="true"
[cdkConnectedOverlayBackdropClass]="'cdk-overlay-transparent-backdrop'"
(backdropClick)="isOpen = false"
(detach)="close()"
>
<div class="box-content">
<div class="environment-selector-dialog" [@transformPanel]="'open'" role="dialog">
<div
class="environment-selector-dialog"
[@transformPanel]="'open'"
cdkTrapFocus
cdkTrapFocusAutoCapture
role="dialog"
aria-modal="true"
>
<button
type="button"
class="environment-selector-dialog-item"
(click)="toggle(ServerEnvironmentType.US)"
[attr.aria-pressed]="selectedEnvironment === ServerEnvironmentType.US ? 'true' : 'false'"
>
<i
class="bwi bwi-fw bwi-sm bwi-check"
@ -51,6 +62,7 @@
type="button"
class="environment-selector-dialog-item"
(click)="toggle(ServerEnvironmentType.EU)"
[attr.aria-pressed]="selectedEnvironment === ServerEnvironmentType.EU ? 'true' : 'false'"
*ngIf="euServerFlagEnabled"
>
<i
@ -68,6 +80,9 @@
type="button"
class="environment-selector-dialog-item"
(click)="toggle(ServerEnvironmentType.SelfHosted)"
[attr.aria-pressed]="
selectedEnvironment === ServerEnvironmentType.SelfHosted ? 'true' : 'false'
"
>
<i
class="bwi bwi-fw bwi-sm bwi-check"

View File

@ -352,7 +352,7 @@ describe("SsoComponent", () => {
describe("Given Trusted Device Encryption is enabled, user doesn't need to set a MP, and forcePasswordReset is required", () => {
[
ForceResetPasswordReason.AdminForcePasswordReset,
ForceResetPasswordReason.WeakMasterPassword,
// ForceResetPasswordReason.WeakMasterPassword, -- not possible in SSO flow as set client side
].forEach((forceResetPasswordReason) => {
const reasonString = ForceResetPasswordReason[forceResetPasswordReason];
let authResult;
@ -449,7 +449,7 @@ describe("SsoComponent", () => {
describe("Force Master Password Reset scenarios", () => {
[
ForceResetPasswordReason.AdminForcePasswordReset,
ForceResetPasswordReason.WeakMasterPassword,
// ForceResetPasswordReason.WeakMasterPassword, -- not possible in SSO flow as set client side
].forEach((forceResetPasswordReason) => {
const reasonString = ForceResetPasswordReason[forceResetPasswordReason];

View File

@ -226,9 +226,9 @@ export class SsoComponent {
return await this.handleChangePasswordRequired(orgIdentifier);
}
// Users can be forced to reset their password via an admin or org policy
// disallowing weak passwords
if (authResult.forcePasswordReset !== ForceResetPasswordReason.None) {
// Users enrolled in admin acct recovery can be forced to set a new password after
// having the admin set a temp password for them
if (authResult.forcePasswordReset == ForceResetPasswordReason.AdminForcePasswordReset) {
return await this.handleForcePasswordReset(orgIdentifier);
}

View File

@ -282,8 +282,10 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
return await this.handleChangePasswordRequired(orgIdentifier);
}
// Users can be forced to reset their password via an admin or org policy
// disallowing weak passwords
// Users can be forced to reset their password via an admin or org policy disallowing weak passwords
// Note: this is different from SSO component login flow as a user can
// login with MP and then have to pass 2FA to finish login and we can actually
// evaluate if they have a weak password at this time.
if (authResult.forcePasswordReset !== ForceResetPasswordReason.None) {
return await this.handleForcePasswordReset(orgIdentifier);
}

View File

@ -154,8 +154,13 @@ export class AddEditComponent implements OnInit, OnDestroy {
.policyAppliesToActiveUser$(PolicyType.SendOptions, (p) => p.data.disableHideEmail)
.pipe(takeUntil(this.destroy$))
.subscribe((policyAppliesToActiveUser) => {
if ((this.disableHideEmail = policyAppliesToActiveUser)) {
if (
(this.disableHideEmail = policyAppliesToActiveUser) &&
!this.formGroup.controls.hideEmail.value
) {
this.formGroup.controls.hideEmail.disable();
} else {
this.formGroup.controls.hideEmail.enable();
}
});
@ -207,9 +212,6 @@ export class AddEditComponent implements OnInit, OnDestroy {
this.send = await send.decrypt();
this.type = this.send.type;
this.updateFormValues();
if (this.send.hideEmail) {
this.formGroup.controls.hideEmail.enable();
}
} else {
this.send = new SendView();
this.send.type = this.type;
@ -425,6 +427,10 @@ export class AddEditComponent implements OnInit, OnDestroy {
"yyyy-MM-ddTHH:mm"
),
});
if (this.send.hideEmail) {
this.formGroup.controls.hideEmail.enable();
}
}
private async handleCopyLinkToClipboard() {

View File

@ -153,6 +153,7 @@ export abstract class LogInStrategy {
const result = new AuthResult();
result.resetMasterPassword = response.resetMasterPassword;
// Convert boolean to enum
if (response.forcePasswordReset) {
result.forcePasswordReset = ForceResetPasswordReason.AdminForcePasswordReset;
}

View File

@ -14,6 +14,7 @@ import { DeviceTrustCryptoServiceAbstraction } from "../abstractions/device-trus
import { KeyConnectorService } from "../abstractions/key-connector.service";
import { TokenService } from "../abstractions/token.service";
import { TwoFactorService } from "../abstractions/two-factor.service";
import { ForceResetPasswordReason } from "../models/domain/force-reset-password-reason";
import { SsoLogInCredentials } from "../models/domain/log-in-credentials";
import { SsoTokenRequest } from "../models/request/identity-token/sso-token.request";
import { IdentityTokenResponse } from "../models/response/identity-token.response";
@ -73,6 +74,11 @@ export class SsoLogInStrategy extends LogInStrategy {
this.email = ssoAuthResult.email;
this.ssoEmail2FaSessionToken = ssoAuthResult.ssoEmail2FaSessionToken;
// Auth guard currently handles redirects for this.
if (ssoAuthResult.forcePasswordReset == ForceResetPasswordReason.AdminForcePasswordReset) {
await this.stateService.setForcePasswordResetReason(ssoAuthResult.forcePasswordReset);
}
return ssoAuthResult;
}

View File

@ -1,3 +1,7 @@
/*
* This enum is used to determine if a user should be forced to reset their password
* on login (server flag) or unlock via MP (client evaluation).
*/
export enum ForceResetPasswordReason {
/**
* A password reset should not be forced.
@ -6,12 +10,14 @@ export enum ForceResetPasswordReason {
/**
* Occurs when an organization admin forces a user to reset their password.
* Communicated via server flag.
*/
AdminForcePasswordReset,
/**
* Occurs when a user logs in / unlocks their vault with a master password that does not meet an organization's
* master password policy that is enforced on login/unlock.
* Only set client side b/c server can't evaluate MP.
*/
WeakMasterPassword,
}

2
package-lock.json generated
View File

@ -230,7 +230,7 @@
},
"apps/desktop": {
"name": "@bitwarden/desktop",
"version": "2023.8.4",
"version": "2023.8.5",
"hasInstallScript": true,
"license": "GPL-3.0"
},