mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-26 12:25:20 +01:00
[PM-10897] Fixing invalid url reference when creating login ciphers from inline menu (#10527)
* [PM-10897] Fixing invalid url reference when creating login ciphers from inline menu * [PM-10897] Ensuring that a subframe that contains a full set of data for a login cipher is treated as authoritative
This commit is contained in:
parent
1cf2c14e82
commit
0b24789449
@ -1299,7 +1299,11 @@ describe("OverlayBackground", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
sender = mock<chrome.runtime.MessageSender>({ tab: { id: 1 } });
|
||||
sender = mock<chrome.runtime.MessageSender>({
|
||||
tab: { id: 1 },
|
||||
url: "https://top-frame-test.com",
|
||||
frameId: 0,
|
||||
});
|
||||
openAddEditVaultItemPopoutSpy = jest
|
||||
.spyOn(overlayBackground as any, "openAddEditVaultItemPopout")
|
||||
.mockImplementation();
|
||||
@ -1482,10 +1486,15 @@ describe("OverlayBackground", () => {
|
||||
|
||||
describe("pulling cipher data from multiple frames of a tab", () => {
|
||||
let subFrameSender: MockProxy<chrome.runtime.MessageSender>;
|
||||
let secondSubFrameSender: MockProxy<chrome.runtime.MessageSender>;
|
||||
const command = "autofillOverlayAddNewVaultItem";
|
||||
|
||||
beforeEach(() => {
|
||||
subFrameSender = mock<chrome.runtime.MessageSender>({ tab: sender.tab, frameId: 2 });
|
||||
secondSubFrameSender = mock<chrome.runtime.MessageSender>({
|
||||
tab: sender.tab,
|
||||
frameId: 3,
|
||||
});
|
||||
});
|
||||
|
||||
it("combines the login cipher data from all frames", async () => {
|
||||
@ -1494,9 +1503,15 @@ describe("OverlayBackground", () => {
|
||||
"buildLoginCipherView",
|
||||
);
|
||||
const addNewCipherType = CipherType.Login;
|
||||
const topLevelLoginCipherData = {
|
||||
uri: "https://top-frame-test.com",
|
||||
hostname: "top-frame-test.com",
|
||||
username: "",
|
||||
password: "",
|
||||
};
|
||||
const loginCipherData = {
|
||||
uri: "https://tacos.com",
|
||||
hostname: "",
|
||||
hostname: "tacos.com",
|
||||
username: "username",
|
||||
password: "",
|
||||
};
|
||||
@ -1507,11 +1522,56 @@ describe("OverlayBackground", () => {
|
||||
password: "password",
|
||||
};
|
||||
|
||||
sendMockExtensionMessage({ command, addNewCipherType, login: loginCipherData }, sender);
|
||||
sendMockExtensionMessage(
|
||||
{ command, addNewCipherType, login: topLevelLoginCipherData },
|
||||
sender,
|
||||
);
|
||||
sendMockExtensionMessage(
|
||||
{ command, addNewCipherType, login: loginCipherData },
|
||||
subFrameSender,
|
||||
);
|
||||
sendMockExtensionMessage(
|
||||
{ command, addNewCipherType, login: subFrameLoginCipherData },
|
||||
secondSubFrameSender,
|
||||
);
|
||||
jest.advanceTimersByTime(100);
|
||||
await flushPromises();
|
||||
|
||||
expect(buildLoginCipherViewSpy).toHaveBeenCalledWith({
|
||||
uri: "https://top-frame-test.com",
|
||||
hostname: "top-frame-test.com",
|
||||
username: "username",
|
||||
password: "password",
|
||||
});
|
||||
});
|
||||
|
||||
it("sets the uri to the subframe of a tab if the login data is complete", async () => {
|
||||
const buildLoginCipherViewSpy = jest.spyOn(
|
||||
overlayBackground as any,
|
||||
"buildLoginCipherView",
|
||||
);
|
||||
const addNewCipherType = CipherType.Login;
|
||||
const loginCipherData = {
|
||||
uri: "https://tacos.com",
|
||||
hostname: "tacos.com",
|
||||
username: "username",
|
||||
password: "password",
|
||||
};
|
||||
const topLevelLoginCipherData = {
|
||||
uri: "https://top-frame-test.com",
|
||||
hostname: "top-frame-test.com",
|
||||
username: "",
|
||||
password: "",
|
||||
};
|
||||
|
||||
sendMockExtensionMessage(
|
||||
{ command, addNewCipherType, login: loginCipherData },
|
||||
subFrameSender,
|
||||
);
|
||||
sendMockExtensionMessage(
|
||||
{ command, addNewCipherType, login: topLevelLoginCipherData },
|
||||
sender,
|
||||
);
|
||||
jest.advanceTimersByTime(100);
|
||||
await flushPromises();
|
||||
|
||||
|
@ -1589,7 +1589,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||
}
|
||||
|
||||
if (login && this.isAddingNewLogin()) {
|
||||
this.updateCurrentAddNewItemLogin(login);
|
||||
this.updateCurrentAddNewItemLogin(login, sender);
|
||||
}
|
||||
|
||||
if (card && this.isAddingNewCard()) {
|
||||
@ -1629,22 +1629,56 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||
* login data is already present, the data will be merged with the existing data.
|
||||
*
|
||||
* @param login - The login data captured from the extension message
|
||||
* @param sender - The sender of the extension message
|
||||
*/
|
||||
private updateCurrentAddNewItemLogin(login: NewLoginCipherData) {
|
||||
private updateCurrentAddNewItemLogin(
|
||||
login: NewLoginCipherData,
|
||||
sender: chrome.runtime.MessageSender,
|
||||
) {
|
||||
const { username, password } = login;
|
||||
|
||||
if (this.partialLoginDataFoundInSubFrame(sender, login)) {
|
||||
login.uri = "";
|
||||
login.hostname = "";
|
||||
}
|
||||
|
||||
if (!this.currentAddNewItemData.login) {
|
||||
this.currentAddNewItemData.login = login;
|
||||
return;
|
||||
}
|
||||
|
||||
const currentLoginData = this.currentAddNewItemData.login;
|
||||
if (sender.frameId === 0 && currentLoginData.hostname && !username && !password) {
|
||||
login.uri = "";
|
||||
login.hostname = "";
|
||||
}
|
||||
|
||||
this.currentAddNewItemData.login = {
|
||||
uri: login.uri || currentLoginData.uri,
|
||||
hostname: login.hostname || currentLoginData.hostname,
|
||||
username: login.username || currentLoginData.username,
|
||||
password: login.password || currentLoginData.password,
|
||||
username: username || currentLoginData.username,
|
||||
password: password || currentLoginData.password,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles verifying if the login data for a tab is separated between various
|
||||
* iframe elements. If that is the case, we want to ignore the login uri and
|
||||
* domain to ensure the top frame is treated as the primary source of login data.
|
||||
*
|
||||
* @param sender - The sender of the extension message
|
||||
* @param login - The login data captured from the extension message
|
||||
*/
|
||||
private partialLoginDataFoundInSubFrame(
|
||||
sender: chrome.runtime.MessageSender,
|
||||
login: NewLoginCipherData,
|
||||
) {
|
||||
const { frameId } = sender;
|
||||
const { username, password } = login;
|
||||
|
||||
return frameId !== 0 && (!username || !password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current add new item data with the provided card data. If the
|
||||
* card data is already present, the data will be merged with the existing data.
|
||||
|
Loading…
Reference in New Issue
Block a user