Skip to content

Commit

Permalink
Merge pull request #2093 from keepassxreboot/feature/autofill_single_…
Browse files Browse the repository at this point in the history
…totp

Add option to fill TOTP automatically
  • Loading branch information
varjolintu authored Jan 27, 2024
2 parents 2c07677 + b773934 commit 6b3e189
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 2 deletions.
8 changes: 8 additions & 0 deletions keepassxc-browser/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,10 @@
"message": "Automatically fill in single-credential entries.",
"description": "Automatically fill-in single credential entry checkbox text."
},
"optionsCheckboxAutoFillSingleTotp": {
"message": "Automatically fill in single TOTP entries.",
"description": "Automatically fill-in single TOTP entries checkbox text."
},
"optionsCheckboxAutoCompleteUsernames": {
"message": "Activate autocomplete for username fields.",
"description": "Activate autocomplete for username fields checkbox text."
Expand Down Expand Up @@ -847,6 +851,10 @@
"message": "Warning! Using auto-fill is not safe. Use at your own risk. KeePassXC-Browser automatically tries to detect login fields. However, they may be detected incorrectly, possibly filling sensitive data to unsafe input fields.",
"description": "Auto-Fill Single Entry warning text."
},
"optionsAutoFillSingleTotpHelpText": {
"message": "Let KeePassXC-Browser automatically fill in TOTP fields if it receives only a single entry.",
"description": "Auto-Fill Single TOTP field option help text."
},
"optionsAutocompleteUsernamesHelpText": {
"message": "Show a dropdown list containing available credentials for all username fields on a page.",
"description": "Autocomplete Usernames option help text."
Expand Down
1 change: 1 addition & 0 deletions keepassxc-browser/background/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const defaultSettings = {
showGroupNameInAutocomplete: true,
autoFillAndSend: false,
autoFillSingleEntry: false,
autoFillSingleTotp: false,
autoReconnect: false,
autoRetrieveCredentials: true,
autoSubmit: false,
Expand Down
8 changes: 8 additions & 0 deletions keepassxc-browser/content/fill.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,14 @@ kpxcFill.fillInCredentials = async function(combination, predefinedUsername, uui
kpxcFill.fillInStringFields(combination.fields, selectedCredentials.stringFields);
}

// Fill TOTP
if (kpxc.settings.autoFillSingleTotp && kpxc.entryHasTotp(selectedCredentials)) {
const totpCombination = combination?.totp || kpxc.combinations?.find(c => c.totp);
if (totpCombination?.totp) {
kpxcFill.fillTOTPFromUuid(totpCombination.totp, selectedCredentials.uuid);
}
}

// Close autocomplete menu after fill
kpxcUserAutocomplete.closeList();

Expand Down
6 changes: 5 additions & 1 deletion keepassxc-browser/content/keepassxc-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ kpxc.detectDatabaseChange = async function(response) {
}
};

kpxc.entryHasTotp = function(entry) {
return entry.totp || (entry.stringFields && entry.stringFields.some(s => s['KPH: {TOTP}']));
};

// Get location URL by domain or full URL
kpxc.getDocumentLocation = function() {
return kpxc.settings.saveDomainOnly ? document.location.origin : document.location.href;
Expand Down Expand Up @@ -776,7 +780,7 @@ kpxc.updateTOTPList = async function() {
const password = credentials.password;

// If no username is set, compare with a password
const credentialList = kpxc.credentials.filter(c => (c.totp || (c.stringFields && c.stringFields.some(s => s['KPH: {TOTP}'])))
const credentialList = kpxc.credentials.filter(c => kpxc.entryHasTotp(c)
&& (c.login === username || (!username && c.password === password)));

// Filter TOTP Autocomplete Menu with matching 2FA credentials
Expand Down
17 changes: 16 additions & 1 deletion keepassxc-browser/content/totp-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,29 @@ class TOTPFieldIcon extends Icon {
}
}

TOTPFieldIcon.prototype.initField = function(field, segmented) {
// Fill TOTP automatically if option is enabled
TOTPFieldIcon.prototype.autoFillSingleTotp = async function(field) {
if (kpxc.settings.autoFillSingleTotp) {
if (kpxc.credentials.length === 0) {
await kpxc.receiveCredentialsIfNecessary();
}

if (kpxc.credentials?.length === 1 && kpxc.entryHasTotp(kpxc.credentials[0])) {
kpxcFill.fillTOTPFromUuid(field, kpxc.credentials[0].uuid);
}
}
};

TOTPFieldIcon.prototype.initField = async function(field, segmented) {
// Observer the visibility
if (this.observer) {
this.observer.observe(field);
}

this.createIcon(field, segmented);
this.inputField = field;

await this.autoFillSingleTotp(field);
};

TOTPFieldIcon.prototype.createIcon = function(field, segmented = false) {
Expand Down
9 changes: 9 additions & 0 deletions keepassxc-browser/options/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,15 @@ <h2 class="pb-3 mt-0" data-i18n="optionsGeneralSettingsTab"></h2>
</div>
</div>

<!-- Automatically fill single-credential TOTP fields -->
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="autoFillSingleTotp" id="autoFillSingleTotp" value="true">
<label class="form-check-label" for="autoFillSingleTotp" data-i18n="optionsCheckboxAutoFillSingleTotp"></label>
<div class="form-text" data-i18n="optionsAutoFillSingleTotpHelpText"></div>
</div>
</div>

<!-- Autofill HTTP Auth dialogs -->
<div class="form-group">
<div class="form-check">
Expand Down

0 comments on commit 6b3e189

Please sign in to comment.