1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-14 15:23:33 +00:00

Merge branch 'master' into feature/flexible-collections

This commit is contained in:
Vincent Salucci
2023-09-19 15:41:56 -05:00
18 changed files with 90 additions and 41 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@bitwarden/browser", "name": "@bitwarden/browser",
"version": "2023.8.3", "version": "2023.9.0",
"scripts": { "scripts": {
"build": "webpack", "build": "webpack",
"build:mv3": "cross-env MANIFEST_VERSION=3 webpack", "build:mv3": "cross-env MANIFEST_VERSION=3 webpack",

View File

@@ -189,7 +189,7 @@ export class ContextMenuClickedHandler {
// we are actually unlocked we will do our best to find a good match of an item to autofill this is useful // we are actually unlocked we will do our best to find a good match of an item to autofill this is useful
// in scenarios like unlock on autofill // in scenarios like unlock on autofill
const ciphers = await this.cipherService.getAllDecryptedForUrl(tab.url); const ciphers = await this.cipherService.getAllDecryptedForUrl(tab.url);
cipher = ciphers.find((c) => c.reprompt === CipherRepromptType.None); cipher = ciphers[0];
} else { } else {
const ciphers = await this.cipherService.getAllDecrypted(); const ciphers = await this.cipherService.getAllDecrypted();
cipher = ciphers.find((c) => c.id === id); cipher = ciphers.find((c) => c.id === id);

View File

@@ -986,13 +986,18 @@
styleTimeout = 200; styleTimeout = 200;
/** /**
* Fll an element `el` using the value `op` from the fill script * Fill an element `el` using the value `op` from the fill script
* @param {HTMLElement} el * @param {HTMLElement} el
* @param {string} op * @param {string} op
*/ */
function fillTheElement(el, op) { function fillTheElement(el, op) {
var shouldCheck; var shouldCheck;
if (el && null !== op && void 0 !== op && !(el.disabled || el.a || el.readOnly)) { if (el && null !== op && void 0 !== op && !(el.disabled || el.a || el.readOnly)) {
const tabURLChanged = !fillScript.savedUrls?.some(url => url.startsWith(window.location.origin))
// Check to make sure the page location didn't change
if (tabURLChanged) {
return;
}
switch (markTheFilling && el.form && !el.form.opfilled && (el.form.opfilled = true), switch (markTheFilling && el.form && !el.form.opfilled && (el.form.opfilled = true),
el.type ? el.type.toLowerCase() : null) { el.type ? el.type.toLowerCase() : null) {
case 'checkbox': case 'checkbox':

View File

@@ -108,6 +108,7 @@ describe("InsertAutofillContentService", () => {
jest.spyOn(insertAutofillContentService as any, "fillingWithinSandboxedIframe"); jest.spyOn(insertAutofillContentService as any, "fillingWithinSandboxedIframe");
jest.spyOn(insertAutofillContentService as any, "userCancelledInsecureUrlAutofill"); jest.spyOn(insertAutofillContentService as any, "userCancelledInsecureUrlAutofill");
jest.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill"); jest.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill");
jest.spyOn(insertAutofillContentService as any, "tabURLChanged");
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction"); jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript); insertAutofillContentService.fillForm(fillScript);
@@ -119,6 +120,7 @@ describe("InsertAutofillContentService", () => {
expect( expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"] insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).not.toHaveBeenCalled(); ).not.toHaveBeenCalled();
expect(insertAutofillContentService["tabURLChanged"]).not.toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled(); expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
}); });
@@ -128,6 +130,7 @@ describe("InsertAutofillContentService", () => {
.mockReturnValue(true); .mockReturnValue(true);
jest.spyOn(insertAutofillContentService as any, "userCancelledInsecureUrlAutofill"); jest.spyOn(insertAutofillContentService as any, "userCancelledInsecureUrlAutofill");
jest.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill"); jest.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill");
jest.spyOn(insertAutofillContentService as any, "tabURLChanged");
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction"); jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript); insertAutofillContentService.fillForm(fillScript);
@@ -139,6 +142,7 @@ describe("InsertAutofillContentService", () => {
expect( expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"] insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).not.toHaveBeenCalled(); ).not.toHaveBeenCalled();
expect(insertAutofillContentService["tabURLChanged"]).not.toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled(); expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
}); });
@@ -150,6 +154,7 @@ describe("InsertAutofillContentService", () => {
.spyOn(insertAutofillContentService as any, "userCancelledInsecureUrlAutofill") .spyOn(insertAutofillContentService as any, "userCancelledInsecureUrlAutofill")
.mockReturnValue(true); .mockReturnValue(true);
jest.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill"); jest.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill");
jest.spyOn(insertAutofillContentService as any, "tabURLChanged");
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction"); jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript); insertAutofillContentService.fillForm(fillScript);
@@ -159,6 +164,7 @@ describe("InsertAutofillContentService", () => {
expect( expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"] insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).not.toHaveBeenCalled(); ).not.toHaveBeenCalled();
expect(insertAutofillContentService["tabURLChanged"]).not.toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled(); expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
}); });
@@ -172,6 +178,7 @@ describe("InsertAutofillContentService", () => {
jest jest
.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill") .spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill")
.mockReturnValue(true); .mockReturnValue(true);
jest.spyOn(insertAutofillContentService as any, "tabURLChanged").mockReturnValue(false);
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction"); jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript); insertAutofillContentService.fillForm(fillScript);
@@ -181,6 +188,31 @@ describe("InsertAutofillContentService", () => {
expect( expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"] insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).toHaveBeenCalled(); ).toHaveBeenCalled();
expect(insertAutofillContentService["tabURLChanged"]).not.toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
});
it("returns early if the page location origin does not match against any of the cipher saved URLs", () => {
jest
.spyOn(insertAutofillContentService as any, "fillingWithinSandboxedIframe")
.mockReturnValue(false);
jest
.spyOn(insertAutofillContentService as any, "userCancelledInsecureUrlAutofill")
.mockReturnValue(false);
jest
.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill")
.mockReturnValue(false);
jest.spyOn(insertAutofillContentService as any, "tabURLChanged").mockReturnValue(true);
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript);
expect(insertAutofillContentService["fillingWithinSandboxedIframe"]).toHaveBeenCalled();
expect(insertAutofillContentService["userCancelledInsecureUrlAutofill"]).toHaveBeenCalled();
expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).toHaveBeenCalled();
expect(insertAutofillContentService["tabURLChanged"]).toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled(); expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
}); });
@@ -194,6 +226,7 @@ describe("InsertAutofillContentService", () => {
jest jest
.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill") .spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill")
.mockReturnValue(false); .mockReturnValue(false);
jest.spyOn(insertAutofillContentService as any, "tabURLChanged").mockReturnValue(false);
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction"); jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript); insertAutofillContentService.fillForm(fillScript);
@@ -203,6 +236,7 @@ describe("InsertAutofillContentService", () => {
expect( expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"] insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).toHaveBeenCalled(); ).toHaveBeenCalled();
expect(insertAutofillContentService["tabURLChanged"]).toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenCalledTimes(3); expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenCalledTimes(3);
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenNthCalledWith( expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenNthCalledWith(
1, 1,

View File

@@ -38,7 +38,8 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
!fillScript.script?.length || !fillScript.script?.length ||
this.fillingWithinSandboxedIframe() || this.fillingWithinSandboxedIframe() ||
this.userCancelledInsecureUrlAutofill(fillScript.savedUrls) || this.userCancelledInsecureUrlAutofill(fillScript.savedUrls) ||
this.userCancelledUntrustedIframeAutofill(fillScript) this.userCancelledUntrustedIframeAutofill(fillScript) ||
this.tabURLChanged(fillScript.savedUrls)
) { ) {
return; return;
} }
@@ -46,6 +47,16 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
fillScript.script.forEach(this.runFillScriptAction); fillScript.script.forEach(this.runFillScriptAction);
} }
/**
* Determines if the page URL no longer matches one of the cipher's savedURL domains
* @param {string[] | null} savedUrls
* @returns {boolean}
* @private
*/
private tabURLChanged(savedUrls?: AutofillScript["savedUrls"]): boolean {
return savedUrls && !savedUrls.some((url) => url.startsWith(window.location.origin));
}
/** /**
* Identifies if the execution of this script is happening * Identifies if the execution of this script is happening
* within a sandboxed iframe. * within a sandboxed iframe.

View File

@@ -2,7 +2,7 @@
"manifest_version": 2, "manifest_version": 2,
"name": "__MSG_extName__", "name": "__MSG_extName__",
"short_name": "__MSG_appName__", "short_name": "__MSG_appName__",
"version": "2023.8.3", "version": "2023.9.0",
"description": "__MSG_extDesc__", "description": "__MSG_extDesc__",
"default_locale": "en", "default_locale": "en",
"author": "Bitwarden Inc.", "author": "Bitwarden Inc.",

View File

@@ -3,7 +3,7 @@
"minimum_chrome_version": "102.0", "minimum_chrome_version": "102.0",
"name": "__MSG_extName__", "name": "__MSG_extName__",
"short_name": "__MSG_appName__", "short_name": "__MSG_appName__",
"version": "2023.8.3", "version": "2023.9.0",
"description": "__MSG_extDesc__", "description": "__MSG_extDesc__",
"default_locale": "en", "default_locale": "en",
"author": "Bitwarden Inc.", "author": "Bitwarden Inc.",

View File

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

View File

@@ -66,7 +66,7 @@ export class ImportCommand {
try { try {
let contents; let contents;
if (format === "1password1pux") { if (format === "1password1pux" && filepath.endsWith(".1pux")) {
contents = await CliUtils.extractZipContent(filepath, "export.data"); contents = await CliUtils.extractZipContent(filepath, "export.data");
} else if (format === "protonpass" && filepath.endsWith(".zip")) { } else if (format === "protonpass" && filepath.endsWith(".zip")) {
contents = await CliUtils.extractZipContent(filepath, "Proton Pass/data.json"); contents = await CliUtils.extractZipContent(filepath, "Proton Pass/data.json");

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
{ {
"name": "@bitwarden/web-vault", "name": "@bitwarden/web-vault",
"version": "2023.8.4", "version": "2023.9.0",
"scripts": { "scripts": {
"build:oss": "webpack", "build:oss": "webpack",
"build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js", "build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js",

View File

@@ -309,7 +309,7 @@ export class ImportComponent implements OnInit, OnDestroy {
} }
private getFileContents(file: File): Promise<string> { private getFileContents(file: File): Promise<string> {
if (this.format === "1password1pux") { if (this.format === "1password1pux" && file.name.endsWith(".1pux")) {
return this.extractZipContent(file, "export.data"); return this.extractZipContent(file, "export.data");
} }
if ( if (

View File

@@ -142,7 +142,7 @@
"message": "文件夹" "message": "文件夹"
}, },
"newCustomField": { "newCustomField": {
"message": "新自定义字段" "message": "新自定义字段"
}, },
"value": { "value": {
"message": "值" "message": "值"
@@ -606,13 +606,13 @@
"message": "登录或者创建一个账户来访问您的安全密码库。" "message": "登录或者创建一个账户来访问您的安全密码库。"
}, },
"loginWithDevice": { "loginWithDevice": {
"message": "使用设备登录" "message": "设备登录"
}, },
"loginWithDeviceEnabledNote": { "loginWithDeviceEnabledNote": {
"message": "设备登录必须在 Bitwarden 应用程序的设置中启用。需要其他登录选项吗?" "message": "设备登录必须在 Bitwarden 应用程序的设置中启用。需要其他登录选项吗?"
}, },
"loginWithMasterPassword": { "loginWithMasterPassword": {
"message": "使用主密码登录" "message": "主密码登录"
}, },
"createAccount": { "createAccount": {
"message": "创建账户" "message": "创建账户"
@@ -791,7 +791,7 @@
"message": "请输入验证器应用程序中的 6 位验证码。" "message": "请输入验证器应用程序中的 6 位验证码。"
}, },
"enterVerificationCodeEmail": { "enterVerificationCodeEmail": {
"message": "请输入发送给电子邮件 $EMAIL$ 的 6 位验证码。", "message": "请输入发送给电子邮件 $EMAIL$ 的 6 位验证码。",
"placeholders": { "placeholders": {
"email": { "email": {
"content": "$1", "content": "$1",
@@ -812,7 +812,7 @@
"message": "记住我" "message": "记住我"
}, },
"sendVerificationCodeEmailAgain": { "sendVerificationCodeEmailAgain": {
"message": "重发验证码电子邮件" "message": "再次发送验证码电子邮件"
}, },
"useAnotherTwoStepMethod": { "useAnotherTwoStepMethod": {
"message": "使用其他两步登录方式" "message": "使用其他两步登录方式"
@@ -1104,7 +1104,7 @@
"message": "继续操作将更改您的账户电子邮件地址。这不会更改用于双重身份验证的电子邮件地址。您可以在两步登录设置中更改它。" "message": "继续操作将更改您的账户电子邮件地址。这不会更改用于双重身份验证的电子邮件地址。您可以在两步登录设置中更改它。"
}, },
"newEmail": { "newEmail": {
"message": "新电子邮件" "message": "新电子邮件地址"
}, },
"code": { "code": {
"message": "代码" "message": "代码"
@@ -1663,7 +1663,7 @@
"message": "单击下面的「保存」按钮,以启用此安全钥匙用于两步登录。" "message": "单击下面的「保存」按钮,以启用此安全钥匙用于两步登录。"
}, },
"twoFactorU2fProblemReadingTryAgain": { "twoFactorU2fProblemReadingTryAgain": {
"message": "读取安全钥匙时出现问题,请再试一次。" "message": "读取安全钥匙时出现问题,请重试。"
}, },
"twoFactorWebAuthnWarning": { "twoFactorWebAuthnWarning": {
"message": "由于平台限制,无法在所有 Bitwarden 应用程序中使用 WebAuthn。您应该启用另一个两步登录提供程序以便在 WebAuthn 无法使用时可以访问您的账户。支持的平台有:" "message": "由于平台限制,无法在所有 Bitwarden 应用程序中使用 WebAuthn。您应该启用另一个两步登录提供程序以便在 WebAuthn 无法使用时可以访问您的账户。支持的平台有:"
@@ -1968,7 +1968,7 @@
} }
}, },
"bitwardenFamiliesPlan": { "bitwardenFamiliesPlan": {
"message": "Bitwarden 家庭计划。" "message": "Bitwarden 家庭计划。"
}, },
"addons": { "addons": {
"message": "附加项目" "message": "附加项目"
@@ -2304,7 +2304,7 @@
} }
}, },
"planNameFamilies": { "planNameFamilies": {
"message": "家庭" "message": "家庭"
}, },
"planDescFamilies": { "planDescFamilies": {
"message": "适用于个人使用,与家人和朋友共享。" "message": "适用于个人使用,与家人和朋友共享。"
@@ -2499,7 +2499,7 @@
"message": "群组" "message": "群组"
}, },
"newGroup": { "newGroup": {
"message": "新群组" "message": "新群组"
}, },
"addGroup": { "addGroup": {
"message": "添加群组" "message": "添加群组"
@@ -2553,7 +2553,7 @@
"message": "只读" "message": "只读"
}, },
"newCollection": { "newCollection": {
"message": "新集合" "message": "新集合"
}, },
"addCollection": { "addCollection": {
"message": "添加集合" "message": "添加集合"
@@ -4152,7 +4152,7 @@
"message": "紧急访问已批准" "message": "紧急访问已批准"
}, },
"viewDesc": { "viewDesc": {
"message": "可以查看您拥有的密码库中的所有项目。" "message": "可以查看您的密码库中的所有项目。"
}, },
"takeover": { "takeover": {
"message": "接管" "message": "接管"
@@ -4646,7 +4646,7 @@
"message": "回收站中超过 30 天的条目将会被自动删除。" "message": "回收站中超过 30 天的条目将会被自动删除。"
}, },
"trashCleanupWarningSelfHosted": { "trashCleanupWarningSelfHosted": {
"message": "回收站中超过一定时间的目将会被自动删除。" "message": "回收站中超过一定时间的目将会被自动删除。"
}, },
"passwordPrompt": { "passwordPrompt": {
"message": "主密码重新提示" "message": "主密码重新提示"
@@ -4730,7 +4730,7 @@
"message": "错误" "message": "错误"
}, },
"accountRecoveryManageUsers": { "accountRecoveryManageUsers": {
"message": "管理用户也必须授予管理账户恢复的权限" "message": "授予「管理账户恢复」的权限,同时必须授予管理用户」的权限"
}, },
"setupProvider": { "setupProvider": {
"message": "提供商设置" "message": "提供商设置"
@@ -5080,7 +5080,7 @@
"message": "免费 Bitwarden 家庭" "message": "免费 Bitwarden 家庭"
}, },
"sponsoredFamiliesEligible": { "sponsoredFamiliesEligible": {
"message": "您和您的家人可使用免费的 Bitwarden 家庭版计划。即使您不在公司上班,您也可以使用个人电子邮件兑换此计划,以保护您的数据安全。" "message": "您和您的家人有资格享受免费的 Bitwarden 家庭版计划。即使您不在公司上班,您也可以使用个人电子邮件兑换此计划,以保护您的数据安全。"
}, },
"sponsoredFamiliesEligibleCard": { "sponsoredFamiliesEligibleCard": {
"message": "立即兑换免费的 Bitwarden 家庭版计划,即使您不在公司上班也能确保您的数据安全。" "message": "立即兑换免费的 Bitwarden 家庭版计划,即使您不在公司上班也能确保您的数据安全。"
@@ -5374,19 +5374,19 @@
"message": "计费同步令牌" "message": "计费同步令牌"
}, },
"active": { "active": {
"message": "生效" "message": "生效"
}, },
"inactive": { "inactive": {
"message": "已失效" "message": "已失效"
}, },
"sentAwaitingSync": { "sentAwaitingSync": {
"message": "已发送(正在等待同步)" "message": "已发送(等待同步)"
}, },
"sent": { "sent": {
"message": "发送" "message": "发送"
}, },
"requestRemoved": { "requestRemoved": {
"message": "已移除(正在等待同步)" "message": "已移除(等待同步)"
}, },
"requested": { "requested": {
"message": "已请求" "message": "已请求"
@@ -5614,7 +5614,7 @@
"message": "启用设备验证" "message": "启用设备验证"
}, },
"deviceVerificationDesc": { "deviceVerificationDesc": {
"message": "登录未识别的设备时,验证码会发送到您的电子邮件地址" "message": "登录未识别的设备时,验证码会发送到您的电子邮"
}, },
"updatedDeviceVerification": { "updatedDeviceVerification": {
"message": "已更新设备验证" "message": "已更新设备验证"
@@ -6230,7 +6230,7 @@
"description": "Toast message after deleting one or multiple access tokens." "description": "Toast message after deleting one or multiple access tokens."
}, },
"noAccessTokenSelected": { "noAccessTokenSelected": {
"message": "未选中任何要销的访问令牌", "message": "未选中任何要销的访问令牌",
"description": "Toast error message after trying to delete access tokens but not selecting any access tokens." "description": "Toast error message after trying to delete access tokens but not selecting any access tokens."
}, },
"submenu": { "submenu": {

View File

@@ -58,7 +58,6 @@ const commonStyles = [
"before:tw-rounded-md", "before:tw-rounded-md",
"before:tw-transition", "before:tw-transition",
"focus-visible:before:tw-ring-2", "focus-visible:before:tw-ring-2",
"focus-visible:before:tw-ring-text-contrast",
"focus-visible:tw-z-10", "focus-visible:tw-z-10",
]; ];

View File

@@ -12,7 +12,7 @@ export const featuredImportOptions = [
{ id: "keepass2xml", name: "KeePass 2 (xml)" }, { id: "keepass2xml", name: "KeePass 2 (xml)" },
{ id: "lastpasscsv", name: "LastPass (csv)" }, { id: "lastpasscsv", name: "LastPass (csv)" },
{ id: "safaricsv", name: "Safari and macOS (csv)" }, { id: "safaricsv", name: "Safari and macOS (csv)" },
{ id: "1password1pux", name: "1Password (1pux)" }, { id: "1password1pux", name: "1Password (1pux/json)" },
] as const; ] as const;
export const regularImportOptions = [ export const regularImportOptions = [

8
package-lock.json generated
View File

@@ -190,11 +190,11 @@
}, },
"apps/browser": { "apps/browser": {
"name": "@bitwarden/browser", "name": "@bitwarden/browser",
"version": "2023.8.3" "version": "2023.9.0"
}, },
"apps/cli": { "apps/cli": {
"name": "@bitwarden/cli", "name": "@bitwarden/cli",
"version": "2023.8.2", "version": "2023.9.0",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"dependencies": { "dependencies": {
"@koa/multer": "3.0.2", "@koa/multer": "3.0.2",
@@ -230,7 +230,7 @@
}, },
"apps/desktop": { "apps/desktop": {
"name": "@bitwarden/desktop", "name": "@bitwarden/desktop",
"version": "2023.8.5", "version": "2023.9.0",
"hasInstallScript": true, "hasInstallScript": true,
"license": "GPL-3.0" "license": "GPL-3.0"
}, },
@@ -260,7 +260,7 @@
}, },
"apps/web": { "apps/web": {
"name": "@bitwarden/web-vault", "name": "@bitwarden/web-vault",
"version": "2023.8.4" "version": "2023.9.0"
}, },
"libs/angular": { "libs/angular": {
"name": "@bitwarden/angular", "name": "@bitwarden/angular",