mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 06:43:35 +00:00
detect and update password changes
This commit is contained in:
2
jslib
2
jslib
Submodule jslib updated: 41ab22a82f...a1112988c4
@@ -485,6 +485,12 @@
|
|||||||
"notificationNeverSave": {
|
"notificationNeverSave": {
|
||||||
"message": "Never for this website"
|
"message": "Never for this website"
|
||||||
},
|
},
|
||||||
|
"notificationChangeDesc": {
|
||||||
|
"message": "Do you want to update this password in Bitwarden?"
|
||||||
|
},
|
||||||
|
"notificationChangeSave": {
|
||||||
|
"message": "Yes, Update Now"
|
||||||
|
},
|
||||||
"disableContextMenuItem": {
|
"disableContextMenuItem": {
|
||||||
"message": "Disable Context Menu Options"
|
"message": "Disable Context Menu Options"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export default class MainBackground {
|
|||||||
onUpdatedRan: boolean;
|
onUpdatedRan: boolean;
|
||||||
onReplacedRan: boolean;
|
onReplacedRan: boolean;
|
||||||
loginToAutoFill: any = null;
|
loginToAutoFill: any = null;
|
||||||
loginsToAdd: any[] = [];
|
notificationQueue: any[] = [];
|
||||||
|
|
||||||
private commandsBackground: CommandsBackground;
|
private commandsBackground: CommandsBackground;
|
||||||
private contextMenusBackground: ContextMenusBackground;
|
private contextMenusBackground: ContextMenusBackground;
|
||||||
@@ -195,9 +195,8 @@ export default class MainBackground {
|
|||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await this.environmentService.setUrlsFromStorage();
|
await this.environmentService.setUrlsFromStorage();
|
||||||
await this.setIcon();
|
await this.setIcon();
|
||||||
this.cleanupLoginsToAdd();
|
this.cleanupNotificationQueue();
|
||||||
await this.fullSync(true);
|
await this.fullSync(true);
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
}, 500);
|
}, 500);
|
||||||
});
|
});
|
||||||
@@ -284,19 +283,19 @@ export default class MainBackground {
|
|||||||
}, options);
|
}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkLoginsToAdd(tab: any = null): Promise<any> {
|
async checkNotificationQueue(tab: any = null): Promise<any> {
|
||||||
if (!this.loginsToAdd.length) {
|
if (this.notificationQueue.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tab != null) {
|
if (tab != null) {
|
||||||
this.doCheck(tab);
|
this.doNotificationQueueCheck(tab);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentTab = await BrowserApi.getTabFromCurrentWindow();
|
const currentTab = await BrowserApi.getTabFromCurrentWindow();
|
||||||
if (currentTab != null) {
|
if (currentTab != null) {
|
||||||
this.doCheck(currentTab);
|
this.doNotificationQueueCheck(currentTab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,17 +498,16 @@ export default class MainBackground {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private cleanupLoginsToAdd() {
|
private cleanupNotificationQueue() {
|
||||||
for (let i = this.loginsToAdd.length - 1; i >= 0; i--) {
|
for (let i = this.notificationQueue.length - 1; i >= 0; i--) {
|
||||||
if (this.loginsToAdd[i].expires < new Date()) {
|
if (this.notificationQueue[i].expires < new Date()) {
|
||||||
this.loginsToAdd.splice(i, 1);
|
this.notificationQueue.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setTimeout(() => this.cleanupNotificationQueue(), 2 * 60 * 1000); // check every 2 minutes
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(() => this.cleanupLoginsToAdd(), 2 * 60 * 1000); // check every 2 minutes
|
private doNotificationQueueCheck(tab: any) {
|
||||||
}
|
|
||||||
|
|
||||||
private doCheck(tab: any) {
|
|
||||||
if (tab == null) {
|
if (tab == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -519,14 +517,19 @@ export default class MainBackground {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this.loginsToAdd.length; i++) {
|
for (let i = 0; i < this.notificationQueue.length; i++) {
|
||||||
if (this.loginsToAdd[i].tabId !== tab.id || this.loginsToAdd[i].domain !== tabDomain) {
|
if (this.notificationQueue[i].tabId !== tab.id || this.notificationQueue[i].domain !== tabDomain) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (this.notificationQueue[i].type === 'addLogin') {
|
||||||
BrowserApi.tabSendMessageData(tab, 'openNotificationBar', {
|
BrowserApi.tabSendMessageData(tab, 'openNotificationBar', {
|
||||||
type: 'add',
|
type: 'add',
|
||||||
});
|
});
|
||||||
|
} else if (this.notificationQueue[i].type === 'changePassword') {
|
||||||
|
BrowserApi.tabSendMessageData(tab, 'openNotificationBar', {
|
||||||
|
type: 'change',
|
||||||
|
});
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,12 +114,19 @@ export default class RuntimeBackground {
|
|||||||
case 'bgAddLogin':
|
case 'bgAddLogin':
|
||||||
await this.addLogin(msg.login, sender.tab);
|
await this.addLogin(msg.login, sender.tab);
|
||||||
break;
|
break;
|
||||||
|
case 'bgChangedPassword':
|
||||||
|
await this.changedPassword(msg.data, sender.tab);
|
||||||
|
break;
|
||||||
case 'bgAddClose':
|
case 'bgAddClose':
|
||||||
this.removeAddLogin(sender.tab);
|
case 'bgChangeClose':
|
||||||
|
this.removeTabFromNotificationQueue(sender.tab);
|
||||||
break;
|
break;
|
||||||
case 'bgAddSave':
|
case 'bgAddSave':
|
||||||
await this.saveAddLogin(sender.tab);
|
await this.saveAddLogin(sender.tab);
|
||||||
break;
|
break;
|
||||||
|
case 'bgChangeSave':
|
||||||
|
await this.saveChangePassword(sender.tab);
|
||||||
|
break;
|
||||||
case 'bgNeverSave':
|
case 'bgNeverSave':
|
||||||
await this.saveNever(sender.tab);
|
await this.saveNever(sender.tab);
|
||||||
break;
|
break;
|
||||||
@@ -181,27 +188,27 @@ export default class RuntimeBackground {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async saveAddLogin(tab: any) {
|
private async saveAddLogin(tab: any) {
|
||||||
for (let i = this.main.loginsToAdd.length - 1; i >= 0; i--) {
|
for (let i = this.main.notificationQueue.length - 1; i >= 0; i--) {
|
||||||
if (this.main.loginsToAdd[i].tabId !== tab.id) {
|
const queueMessage = this.main.notificationQueue[i];
|
||||||
|
if (queueMessage.tabId !== tab.id || queueMessage.type !== 'addLogin') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const loginInfo = this.main.loginsToAdd[i];
|
|
||||||
const tabDomain = this.platformUtilsService.getDomain(tab.url);
|
const tabDomain = this.platformUtilsService.getDomain(tab.url);
|
||||||
if (tabDomain != null && tabDomain !== loginInfo.domain) {
|
if (tabDomain != null && tabDomain !== queueMessage.domain) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.main.loginsToAdd.splice(i, 1);
|
this.main.notificationQueue.splice(i, 1);
|
||||||
|
|
||||||
const loginModel = new LoginView();
|
const loginModel = new LoginView();
|
||||||
const loginUri = new LoginUriView();
|
const loginUri = new LoginUriView();
|
||||||
loginUri.uri = loginInfo.uri;
|
loginUri.uri = queueMessage.uri;
|
||||||
loginModel.uris = [loginUri];
|
loginModel.uris = [loginUri];
|
||||||
loginModel.username = loginInfo.username;
|
loginModel.username = queueMessage.username;
|
||||||
loginModel.password = loginInfo.password;
|
loginModel.password = queueMessage.password;
|
||||||
const model = new CipherView();
|
const model = new CipherView();
|
||||||
model.name = Utils.getHostname(loginInfo.uri) || loginInfo.domain;
|
model.name = Utils.getHostname(queueMessage.uri) || queueMessage.domain;
|
||||||
model.type = CipherType.Login;
|
model.type = CipherType.Login;
|
||||||
model.login = loginModel;
|
model.login = loginModel;
|
||||||
|
|
||||||
@@ -216,19 +223,49 @@ export default class RuntimeBackground {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async saveNever(tab: any) {
|
private async saveChangePassword(tab: any) {
|
||||||
for (let i = this.main.loginsToAdd.length - 1; i >= 0; i--) {
|
for (let i = this.main.notificationQueue.length - 1; i >= 0; i--) {
|
||||||
if (this.main.loginsToAdd[i].tabId !== tab.id) {
|
const queueMessage = this.main.notificationQueue[i];
|
||||||
|
if (queueMessage.tabId !== tab.id || queueMessage.type !== 'changePassword') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const loginInfo = this.main.loginsToAdd[i];
|
|
||||||
const tabDomain = this.platformUtilsService.getDomain(tab.url);
|
const tabDomain = this.platformUtilsService.getDomain(tab.url);
|
||||||
if (tabDomain != null && tabDomain !== loginInfo.domain) {
|
if (tabDomain != null && tabDomain !== queueMessage.domain) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.main.loginsToAdd.splice(i, 1);
|
this.main.notificationQueue.splice(i, 1);
|
||||||
|
|
||||||
|
const cipher = await this.cipherService.get(queueMessage.cipherId);
|
||||||
|
if (cipher != null && cipher.type === CipherType.Login) {
|
||||||
|
const model = await cipher.decrypt();
|
||||||
|
model.login.password = queueMessage.newPassword;
|
||||||
|
const newCipher = await this.cipherService.encrypt(model);
|
||||||
|
await this.cipherService.saveWithServer(newCipher);
|
||||||
|
this.analytics.ga('send', {
|
||||||
|
hitType: 'event',
|
||||||
|
eventAction: 'Changed Password from Notification Bar',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
BrowserApi.tabSendMessageData(tab, 'closeNotificationBar');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async saveNever(tab: any) {
|
||||||
|
for (let i = this.main.notificationQueue.length - 1; i >= 0; i--) {
|
||||||
|
const queueMessage = this.main.notificationQueue[i];
|
||||||
|
if (queueMessage.tabId !== tab.id || queueMessage.type !== 'addLogin') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabDomain = this.platformUtilsService.getDomain(tab.url);
|
||||||
|
if (tabDomain != null && tabDomain !== queueMessage.domain) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.main.notificationQueue.splice(i, 1);
|
||||||
const hostname = Utils.getHostname(tab.url);
|
const hostname = Utils.getHostname(tab.url);
|
||||||
await this.cipherService.saveNeverDomain(hostname);
|
await this.cipherService.saveNeverDomain(hostname);
|
||||||
BrowserApi.tabSendMessageData(tab, 'closeNotificationBar');
|
BrowserApi.tabSendMessageData(tab, 'closeNotificationBar');
|
||||||
@@ -251,10 +288,10 @@ export default class RuntimeBackground {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
// remove any old logins for this tab
|
// remove any old messages for this tab
|
||||||
this.removeAddLogin(tab);
|
this.removeTabFromNotificationQueue(tab);
|
||||||
|
this.main.notificationQueue.push({
|
||||||
this.main.loginsToAdd.push({
|
type: 'addLogin',
|
||||||
username: loginInfo.username,
|
username: loginInfo.username,
|
||||||
password: loginInfo.password,
|
password: loginInfo.password,
|
||||||
domain: loginDomain,
|
domain: loginDomain,
|
||||||
@@ -262,15 +299,37 @@ export default class RuntimeBackground {
|
|||||||
tabId: tab.id,
|
tabId: tab.id,
|
||||||
expires: new Date((new Date()).getTime() + 30 * 60000), // 30 minutes
|
expires: new Date((new Date()).getTime() + 30 * 60000), // 30 minutes
|
||||||
});
|
});
|
||||||
|
await this.main.checkNotificationQueue(tab);
|
||||||
await this.main.checkLoginsToAdd(tab);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeAddLogin(tab: any) {
|
private async changedPassword(changeData: any, tab: any) {
|
||||||
for (let i = this.main.loginsToAdd.length - 1; i >= 0; i--) {
|
const loginDomain = this.platformUtilsService.getDomain(changeData.url);
|
||||||
if (this.main.loginsToAdd[i].tabId === tab.id) {
|
if (loginDomain == null) {
|
||||||
this.main.loginsToAdd.splice(i, 1);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ciphers = await this.cipherService.getAllDecryptedForUrl(changeData.url);
|
||||||
|
const matches = ciphers.filter((c) => c.login.password === changeData.currentPassword);
|
||||||
|
if (matches.length === 1) {
|
||||||
|
// remove any old messages for this tab
|
||||||
|
this.removeTabFromNotificationQueue(tab);
|
||||||
|
this.main.notificationQueue.push({
|
||||||
|
type: 'changePassword',
|
||||||
|
cipherId: matches[0].id,
|
||||||
|
newPassword: changeData.newPassword,
|
||||||
|
domain: loginDomain,
|
||||||
|
tabId: tab.id,
|
||||||
|
expires: new Date((new Date()).getTime() + 30 * 60000), // 30 minutes
|
||||||
|
});
|
||||||
|
await this.main.checkNotificationQueue(tab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private removeTabFromNotificationQueue(tab: any) {
|
||||||
|
for (let i = this.main.notificationQueue.length - 1; i >= 0; i--) {
|
||||||
|
if (this.main.notificationQueue[i].tabId === tab.id) {
|
||||||
|
this.main.notificationQueue.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,6 +432,8 @@ export default class RuntimeBackground {
|
|||||||
notificationAddSave: this.i18nService.t('notificationAddSave'),
|
notificationAddSave: this.i18nService.t('notificationAddSave'),
|
||||||
notificationNeverSave: this.i18nService.t('notificationNeverSave'),
|
notificationNeverSave: this.i18nService.t('notificationNeverSave'),
|
||||||
notificationAddDesc: this.i18nService.t('notificationAddDesc'),
|
notificationAddDesc: this.i18nService.t('notificationAddDesc'),
|
||||||
|
notificationChangeSave: this.i18nService.t('notificationChangeSave'),
|
||||||
|
notificationChangeDesc: this.i18nService.t('notificationChangeDesc'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export default class TabsBackground {
|
|||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
this.tabs.addEventListener('navigate', async (ev: any) => {
|
this.tabs.addEventListener('navigate', async (ev: any) => {
|
||||||
await this.main.checkLoginsToAdd();
|
await this.main.checkNotificationQueue();
|
||||||
await this.main.refreshBadgeAndMenu();
|
await this.main.refreshBadgeAndMenu();
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ export default class TabsBackground {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.main.onReplacedRan = true;
|
this.main.onReplacedRan = true;
|
||||||
await this.main.checkLoginsToAdd();
|
await this.main.checkNotificationQueue();
|
||||||
await this.main.refreshBadgeAndMenu();
|
await this.main.refreshBadgeAndMenu();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ export default class TabsBackground {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.main.onUpdatedRan = true;
|
this.main.onUpdatedRan = true;
|
||||||
await this.main.checkLoginsToAdd();
|
await this.main.checkNotificationQueue();
|
||||||
await this.main.refreshBadgeAndMenu();
|
await this.main.refreshBadgeAndMenu();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|||||||
formEl: formEl,
|
formEl: formEl,
|
||||||
usernameEl: null,
|
usernameEl: null,
|
||||||
passwordEl: null,
|
passwordEl: null,
|
||||||
|
passwordEls: null,
|
||||||
};
|
};
|
||||||
locateFields(formDataObj);
|
locateFields(formDataObj);
|
||||||
formData.push(formDataObj);
|
formData.push(formDataObj);
|
||||||
@@ -240,8 +241,8 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|||||||
submitButton.removeEventListener('click', formSubmitted, false);
|
submitButton.removeEventListener('click', formSubmitted, false);
|
||||||
submitButton.addEventListener('click', formSubmitted, false);
|
submitButton.addEventListener('click', formSubmitted, false);
|
||||||
} else {
|
} else {
|
||||||
const possibleSubmitButtons = form.querySelectorAll('a, span, button[type="button"], ' +
|
const possibleSubmitButtons = Array.from(form.querySelectorAll('a, span, button[type="button"], ' +
|
||||||
'input[type="button"]') as NodeListOf<HTMLElement>;
|
'input[type="button"]')) as HTMLElement[];
|
||||||
possibleSubmitButtons.forEach((button) => {
|
possibleSubmitButtons.forEach((button) => {
|
||||||
if (button == null || button.tagName == null) {
|
if (button == null || button.tagName == null) {
|
||||||
return;
|
return;
|
||||||
@@ -268,41 +269,53 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function locateFields(formDataObj: any) {
|
function locateFields(formDataObj: any) {
|
||||||
const passwordId: string = formDataObj.data.password != null ? formDataObj.data.password.htmlID : null;
|
const inputs = Array.from(document.getElementsByTagName('input'));
|
||||||
const usernameId: string = formDataObj.data.username != null ? formDataObj.data.username.htmlID : null;
|
formDataObj.usernameEl = locateField(formDataObj.formEl, formDataObj.data.username, inputs);
|
||||||
const passwordName: string = formDataObj.data.password != null ? formDataObj.data.password.htmlName : null;
|
if (formDataObj.usernameEl != null && formDataObj.data.password != null) {
|
||||||
const usernameName: string = formDataObj.data.username != null ? formDataObj.data.username.htmlName : null;
|
formDataObj.passwordEl = locatePassword(formDataObj.formEl, formDataObj.data.password, inputs, true);
|
||||||
const inputs = document.getElementsByTagName('input');
|
} else if (formDataObj.data.passwords != null && formDataObj.data.passwords.length === 3) {
|
||||||
|
formDataObj.passwordEls = [];
|
||||||
if (passwordId != null && passwordId !== '') {
|
formDataObj.data.passwords.forEach((pData: any) => {
|
||||||
try {
|
const el = locatePassword(formDataObj.formEl, pData, inputs, false);
|
||||||
formDataObj.passwordEl = formDataObj.formEl.querySelector('#' + passwordId);
|
if (el != null) {
|
||||||
} catch { }
|
formDataObj.passwordEls.push(el);
|
||||||
}
|
}
|
||||||
if (formDataObj.passwordEl == null && passwordName !== '') {
|
});
|
||||||
formDataObj.passwordEl = formDataObj.formEl.querySelector('input[name="' + passwordName + '"]');
|
if (formDataObj.passwordEls.length !== 3) {
|
||||||
}
|
formDataObj.passwordEls = null;
|
||||||
if (formDataObj.passwordEl == null && formDataObj.passwordEl != null) {
|
|
||||||
formDataObj.passwordEl = inputs[formDataObj.data.password.elementNumber];
|
|
||||||
if (formDataObj.passwordEl != null && formDataObj.passwordEl.type !== 'password') {
|
|
||||||
formDataObj.passwordEl = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (formDataObj.passwordEl == null) {
|
|
||||||
formDataObj.passwordEl = formDataObj.formEl.querySelector('input[type="password"]');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usernameId != null && usernameId !== '') {
|
function locatePassword(form: HTMLFormElement, passwordData: any, inputs: HTMLInputElement[],
|
||||||
|
doLastFallback: boolean) {
|
||||||
|
let el = locateField(form, passwordData, inputs);
|
||||||
|
if (el != null && el.type !== 'password') {
|
||||||
|
el = null;
|
||||||
|
}
|
||||||
|
if (doLastFallback && el == null) {
|
||||||
|
el = form.querySelector('input[type="password"]');
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
function locateField(form: HTMLFormElement, fieldData: any, inputs: HTMLInputElement[]) {
|
||||||
|
if (fieldData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let el: HTMLInputElement = null;
|
||||||
|
if (fieldData.htmlID != null && fieldData.htmlID !== '') {
|
||||||
try {
|
try {
|
||||||
formDataObj.usernameEl = formDataObj.formEl.querySelector('#' + usernameId);
|
el = form.querySelector('#' + fieldData.htmlID);
|
||||||
} catch { }
|
} catch { }
|
||||||
}
|
}
|
||||||
if (formDataObj.usernameEl == null && usernameName !== '') {
|
if (el == null && fieldData.htmlName != null && fieldData.htmlName !== '') {
|
||||||
formDataObj.usernameEl = formDataObj.formEl.querySelector('input[name="' + usernameName + '"]');
|
el = form.querySelector('input[name="' + fieldData.htmlName + '"]');
|
||||||
}
|
}
|
||||||
if (formDataObj.usernameEl == null && formDataObj.data.username != null) {
|
if (el == null && fieldData.elementNumber != null) {
|
||||||
formDataObj.usernameEl = inputs[formDataObj.data.username.elementNumber];
|
el = inputs[fieldData.elementNumber];
|
||||||
}
|
}
|
||||||
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formSubmitted(e: Event) {
|
function formSubmitted(e: Event) {
|
||||||
@@ -321,22 +334,16 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|||||||
if (formData[i].formEl !== form) {
|
if (formData[i].formEl !== form) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (formData[i].usernameEl == null || formData[i].passwordEl == null) {
|
if (formData[i].usernameEl != null && formData[i].passwordEl != null) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const login = {
|
const login = {
|
||||||
username: formData[i].usernameEl.value,
|
username: formData[i].usernameEl.value,
|
||||||
password: formData[i].passwordEl.value,
|
password: formData[i].passwordEl.value,
|
||||||
url: document.URL,
|
url: document.URL,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (login.username != null && login.username !== '' && login.password != null && login.password !== '') {
|
if (login.username != null && login.username !== '' &&
|
||||||
form.dataset.bitwardenProcessed = '1';
|
login.password != null && login.password !== '') {
|
||||||
window.setTimeout(() => {
|
processedForm(form);
|
||||||
form.dataset.bitwardenProcessed = '0';
|
|
||||||
}, 500);
|
|
||||||
|
|
||||||
sendPlatformMessage({
|
sendPlatformMessage({
|
||||||
command: 'bgAddLogin',
|
command: 'bgAddLogin',
|
||||||
login: login,
|
login: login,
|
||||||
@@ -344,6 +351,40 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (formData[i].passwordEls != null && formData[i].passwordEls.length === 3) {
|
||||||
|
const passwords = formData[i].passwordEls
|
||||||
|
.filter((el: HTMLInputElement) => el.value != null && el.value !== '')
|
||||||
|
.map((el: HTMLInputElement) => el.value);
|
||||||
|
if (passwords.length === 3) {
|
||||||
|
const newPass: string = passwords[1];
|
||||||
|
let curPass: string = null;
|
||||||
|
if (passwords[0] !== newPass && newPass === passwords[2]) {
|
||||||
|
curPass = passwords[0];
|
||||||
|
} else if (newPass !== passwords[2] && passwords[0] === newPass) {
|
||||||
|
curPass = passwords[2];
|
||||||
|
}
|
||||||
|
if (newPass != null && curPass != null) {
|
||||||
|
processedForm(form);
|
||||||
|
sendPlatformMessage({
|
||||||
|
command: 'bgChangedPassword',
|
||||||
|
data: {
|
||||||
|
newPassword: newPass,
|
||||||
|
currentPassword: curPass,
|
||||||
|
url: document.URL,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processedForm(form: HTMLFormElement) {
|
||||||
|
form.dataset.bitwardenProcessed = '1';
|
||||||
|
window.setTimeout(() => {
|
||||||
|
form.dataset.bitwardenProcessed = '0';
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeExistingAndOpenBar(type: string, typeData: any) {
|
function closeExistingAndOpenBar(type: string, typeData: any) {
|
||||||
@@ -364,6 +405,9 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|||||||
case 'add':
|
case 'add':
|
||||||
barPage = barPage + '?add=1';
|
barPage = barPage + '?add=1';
|
||||||
break;
|
break;
|
||||||
|
case 'change':
|
||||||
|
barPage = barPage + '?change=1';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -426,6 +470,11 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|||||||
command: 'bgAddClose',
|
command: 'bgAddClose',
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case 'change':
|
||||||
|
sendPlatformMessage({
|
||||||
|
command: 'bgChangeClose',
|
||||||
|
});
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,16 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<table class="inner-table" cellpadding="0" cellspacing="0" id="template-change">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="change-text"></td>
|
||||||
|
<td align="right" class="change-buttons">
|
||||||
|
<button class="change-save"></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
<div id="template-alert"></div>
|
<div id="template-alert"></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
i18n.notificationAddSave = chrome.i18n.getMessage('notificationAddSave');
|
i18n.notificationAddSave = chrome.i18n.getMessage('notificationAddSave');
|
||||||
i18n.notificationNeverSave = chrome.i18n.getMessage('notificationNeverSave');
|
i18n.notificationNeverSave = chrome.i18n.getMessage('notificationNeverSave');
|
||||||
i18n.notificationAddDesc = chrome.i18n.getMessage('notificationAddDesc');
|
i18n.notificationAddDesc = chrome.i18n.getMessage('notificationAddDesc');
|
||||||
|
i18n.notificationChangeSave = chrome.i18n.getMessage('notificationChangeSave');
|
||||||
|
i18n.notificationChangeDesc = chrome.i18n.getMessage('notificationChangeDesc');
|
||||||
|
|
||||||
// delay 50ms so that we get proper body dimensions
|
// delay 50ms so that we get proper body dimensions
|
||||||
setTimeout(load, 50);
|
setTimeout(load, 50);
|
||||||
@@ -42,12 +44,15 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if (bodyRect.width < 768) {
|
if (bodyRect.width < 768) {
|
||||||
document.querySelector('#template-add .add-save').textContent = i18n.yes;
|
document.querySelector('#template-add .add-save').textContent = i18n.yes;
|
||||||
document.querySelector('#template-add .never-save').textContent = i18n.never;
|
document.querySelector('#template-add .never-save').textContent = i18n.never;
|
||||||
|
document.querySelector('#template-change .change-save').textContent = i18n.yes;
|
||||||
} else {
|
} else {
|
||||||
document.querySelector('#template-add .add-save').textContent = i18n.notificationAddSave;
|
document.querySelector('#template-add .add-save').textContent = i18n.notificationAddSave;
|
||||||
document.querySelector('#template-add .never-save').textContent = i18n.notificationNeverSave;
|
document.querySelector('#template-add .never-save').textContent = i18n.notificationNeverSave;
|
||||||
|
document.querySelector('#template-change .change-save').textContent = i18n.notificationChangeSave;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector('#template-add .add-text').textContent = i18n.notificationAddDesc;
|
document.querySelector('#template-add .add-text').textContent = i18n.notificationAddDesc;
|
||||||
|
document.querySelector('#template-change .change-text').textContent = i18n.notificationChangeDesc;
|
||||||
|
|
||||||
if (getQueryVariable('add')) {
|
if (getQueryVariable('add')) {
|
||||||
setContent(document.getElementById('template-add'));
|
setContent(document.getElementById('template-add'));
|
||||||
@@ -68,6 +73,15 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
command: 'bgNeverSave'
|
command: 'bgNeverSave'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
} else if (getQueryVariable('change')) {
|
||||||
|
setContent(document.getElementById('template-change'));
|
||||||
|
var changeButton = document.querySelector('#template-change-clone .change-save');
|
||||||
|
changeButton.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
sendPlatformMessage({
|
||||||
|
command: 'bgChangeSave'
|
||||||
|
});
|
||||||
|
});
|
||||||
} else if (getQueryVariable('info')) {
|
} else if (getQueryVariable('info')) {
|
||||||
setContent(document.getElementById('template-alert'));
|
setContent(document.getElementById('template-alert'));
|
||||||
document.getElementById('template-alert-clone').textContent = getQueryVariable('info');
|
document.getElementById('template-alert-clone').textContent = getQueryVariable('info');
|
||||||
|
|||||||
@@ -119,24 +119,19 @@ export default class AutofillService implements AutofillServiceInterface {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < passwordFields.length; i++) {
|
const formPasswordFields = passwordFields.filter((pf) => formKey === pf.form);
|
||||||
const pf = passwordFields[i];
|
if (formPasswordFields.length > 0) {
|
||||||
if (formKey !== pf.form) {
|
let uf = this.findUsernameField(pageDetails, formPasswordFields[0], false, false);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let uf = this.findUsernameField(pageDetails, pf, false, false);
|
|
||||||
if (uf == null) {
|
if (uf == null) {
|
||||||
// not able to find any viewable username fields. maybe there are some "hidden" ones?
|
// not able to find any viewable username fields. maybe there are some "hidden" ones?
|
||||||
uf = this.findUsernameField(pageDetails, pf, true, false);
|
uf = this.findUsernameField(pageDetails, formPasswordFields[0], true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
formData.push({
|
formData.push({
|
||||||
form: pageDetails.forms[formKey],
|
form: pageDetails.forms[formKey],
|
||||||
password: pf,
|
password: formPasswordFields[0],
|
||||||
username: uf,
|
username: uf,
|
||||||
|
passwords: formPasswordFields,
|
||||||
});
|
});
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user