From ecb3aa931da543eb5e059335f26fc1af31380940 Mon Sep 17 00:00:00 2001 From: Viktor Wingqvist Date: Tue, 1 Jul 2025 01:22:29 +0200 Subject: [PATCH] fix(profile): Prevent autofill on header search bar This commit resolves the recurring issue where password managers incorrectly autofill the header search bar when viewing the user profile page. This is achieved by wrapping the password change fields in a
element, properly scoping them for browser autofill logic, and using modern, standard `autocomplete` attributes. This addresses the root cause of the issue, whereas previous attempts tried to mitigate the symptom in the search bar. Fixes #2324 Closes #3327 --- client/components/common/nav-header.vue | 4 +- client/components/profile/profile.vue | 68 +++++++++++++------------ 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/client/components/common/nav-header.vue b/client/components/common/nav-header.vue index d8fc3c80..ead24f94 100644 --- a/client/components/common/nav-header.vue +++ b/client/components/common/nav-header.vue @@ -15,7 +15,7 @@ prepend-inner-icon='mdi-magnify' :loading='searchIsLoading' @keyup.enter='searchEnter' - autocomplete='none' + autocomplete='off' ) v-layout(row) v-flex(xs5, md4) @@ -68,7 +68,7 @@ @blur='searchBlur' @keyup.down='searchMove(`down`)' @keyup.up='searchMove(`up`)' - autocomplete='none' + autocomplete='off' ) v-tooltip(bottom) template(v-slot:activator='{ on }') diff --git a/client/components/profile/profile.vue b/client/components/profile/profile.vue index 345476d2..5817df91 100644 --- a/client/components/profile/profile.vue +++ b/client/components/profile/profile.vue @@ -129,41 +129,43 @@ //- v-btn(color='purple darken-4', disabled).ml-0 Enable 2FA //- v-btn(color='purple darken-4', dark, depressed, disabled).ml-0 Disable 2FA template(v-if='user.providerKey === `local`') - v-divider.mt-3 - v-subheader.pl-0: span.subtitle-2 {{$t('profile:auth.changePassword')}} - v-text-field( - ref='iptCurrentPass' - v-model='currentPass' - outlined - :label='$t(`profile:auth.currentPassword`)' - type='password' - prepend-inner-icon='mdi-form-textbox-password' - ) - v-text-field( - ref='iptNewPass' - v-model='newPass' - outlined - :label='$t(`profile:auth.newPassword`)' - type='password' - prepend-inner-icon='mdi-form-textbox-password' - autocomplete='off' - counter='255' - loading - ) - password-strength(slot='progress', v-model='newPass') - v-text-field( - ref='iptVerifyPass' - v-model='verifyPass' - outlined - :label='$t(`profile:auth.verifyPassword`)' - type='password' - prepend-inner-icon='mdi-form-textbox-password' - autocomplete='off' - hide-details - ) + form#change-password-form(@submit.prevent='changePassword') + v-divider.mt-3 + v-subheader.pl-0: span.subtitle-2 {{$t('profile:auth.changePassword')}} + v-text-field( + ref='iptCurrentPass' + v-model='currentPass' + outlined + :label='$t(`profile:auth.currentPassword`)' + type='password' + prepend-inner-icon='mdi-form-textbox-password' + autocomplete='current-password' + ) + v-text-field( + ref='iptNewPass' + v-model='newPass' + outlined + :label='$t(`profile:auth.newPassword`)' + type='password' + prepend-inner-icon='mdi-form-textbox-password' + autocomplete='off' + counter='255' + loading + ) + password-strength(slot='progress', v-model='newPass') + v-text-field( + ref='iptVerifyPass' + v-model='verifyPass' + outlined + :label='$t(`profile:auth.verifyPassword`)' + type='password' + prepend-inner-icon='mdi-form-textbox-password' + autocomplete='off' + hide-details + ) v-card-chin(v-if='user.providerKey === `local`') v-spacer - v-btn.px-4(color='purple darken-4', dark, depressed, @click='changePassword', :loading='changePassLoading') + v-btn.px-4(color='purple darken-4', dark, depressed, :loading='changePassLoading', type='submit', form='change-password-form') v-icon(left) mdi-progress-check span {{$t('profile:auth.changePassword')}} v-flex(lg6 xs12)