1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-01-04 18:37:45 +01:00

Merge branch 'master' into feature/flexible-collections

This commit is contained in:
Vincent Salucci 2023-09-19 15:41:56 -05:00
commit d46cec81d8
No known key found for this signature in database
GPG Key ID: 0B070977863C1E19
18 changed files with 90 additions and 41 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@bitwarden/browser",
"version": "2023.8.3",
"version": "2023.9.0",
"scripts": {
"build": "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
// in scenarios like unlock on autofill
const ciphers = await this.cipherService.getAllDecryptedForUrl(tab.url);
cipher = ciphers.find((c) => c.reprompt === CipherRepromptType.None);
cipher = ciphers[0];
} else {
const ciphers = await this.cipherService.getAllDecrypted();
cipher = ciphers.find((c) => c.id === id);

View File

@ -986,13 +986,18 @@
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 {string} op
*/
function fillTheElement(el, op) {
var shouldCheck;
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),
el.type ? el.type.toLowerCase() : null) {
case 'checkbox':

View File

@ -108,6 +108,7 @@ describe("InsertAutofillContentService", () => {
jest.spyOn(insertAutofillContentService as any, "fillingWithinSandboxedIframe");
jest.spyOn(insertAutofillContentService as any, "userCancelledInsecureUrlAutofill");
jest.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill");
jest.spyOn(insertAutofillContentService as any, "tabURLChanged");
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript);
@ -119,6 +120,7 @@ describe("InsertAutofillContentService", () => {
expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).not.toHaveBeenCalled();
expect(insertAutofillContentService["tabURLChanged"]).not.toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
});
@ -128,6 +130,7 @@ describe("InsertAutofillContentService", () => {
.mockReturnValue(true);
jest.spyOn(insertAutofillContentService as any, "userCancelledInsecureUrlAutofill");
jest.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill");
jest.spyOn(insertAutofillContentService as any, "tabURLChanged");
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript);
@ -139,6 +142,7 @@ describe("InsertAutofillContentService", () => {
expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).not.toHaveBeenCalled();
expect(insertAutofillContentService["tabURLChanged"]).not.toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
});
@ -150,6 +154,7 @@ describe("InsertAutofillContentService", () => {
.spyOn(insertAutofillContentService as any, "userCancelledInsecureUrlAutofill")
.mockReturnValue(true);
jest.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill");
jest.spyOn(insertAutofillContentService as any, "tabURLChanged");
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript);
@ -159,6 +164,7 @@ describe("InsertAutofillContentService", () => {
expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).not.toHaveBeenCalled();
expect(insertAutofillContentService["tabURLChanged"]).not.toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).not.toHaveBeenCalled();
});
@ -172,6 +178,7 @@ describe("InsertAutofillContentService", () => {
jest
.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill")
.mockReturnValue(true);
jest.spyOn(insertAutofillContentService as any, "tabURLChanged").mockReturnValue(false);
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript);
@ -181,6 +188,31 @@ describe("InsertAutofillContentService", () => {
expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).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();
});
@ -194,6 +226,7 @@ describe("InsertAutofillContentService", () => {
jest
.spyOn(insertAutofillContentService as any, "userCancelledUntrustedIframeAutofill")
.mockReturnValue(false);
jest.spyOn(insertAutofillContentService as any, "tabURLChanged").mockReturnValue(false);
jest.spyOn(insertAutofillContentService as any, "runFillScriptAction");
insertAutofillContentService.fillForm(fillScript);
@ -203,6 +236,7 @@ describe("InsertAutofillContentService", () => {
expect(
insertAutofillContentService["userCancelledUntrustedIframeAutofill"]
).toHaveBeenCalled();
expect(insertAutofillContentService["tabURLChanged"]).toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenCalledTimes(3);
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenNthCalledWith(
1,

View File

@ -38,7 +38,8 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
!fillScript.script?.length ||
this.fillingWithinSandboxedIframe() ||
this.userCancelledInsecureUrlAutofill(fillScript.savedUrls) ||
this.userCancelledUntrustedIframeAutofill(fillScript)
this.userCancelledUntrustedIframeAutofill(fillScript) ||
this.tabURLChanged(fillScript.savedUrls)
) {
return;
}
@ -46,6 +47,16 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
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
* within a sandboxed iframe.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,12 @@
{
"name": "@bitwarden/desktop",
"version": "2023.8.5",
"version": "2023.9.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@bitwarden/desktop",
"version": "2023.8.5",
"version": "2023.9.0",
"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.5",
"version": "2023.9.0",
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
"homepage": "https://bitwarden.com",
"license": "GPL-3.0",

View File

@ -1,6 +1,6 @@
{
"name": "@bitwarden/web-vault",
"version": "2023.8.4",
"version": "2023.9.0",
"scripts": {
"build:oss": "webpack",
"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> {
if (this.format === "1password1pux") {
if (this.format === "1password1pux" && file.name.endsWith(".1pux")) {
return this.extractZipContent(file, "export.data");
}
if (

View File

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

View File

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

View File

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

8
package-lock.json generated
View File

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