Skip to content

Commit

Permalink
Add a user pref to reveal dotted passwords - Closes #208
Browse files Browse the repository at this point in the history
  • Loading branch information
Bubka committed Dec 5, 2023
1 parent c75e4eb commit b2e733e
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 7 deletions.
1 change: 1 addition & 0 deletions config/2fauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@

'preferences' => [
'showOtpAsDot' => false,
'revealDottedOTP' => false,
'closeOtpOnCopy' => false,
'copyOtpOnDisplay' => false,
'useBasicQrcodeReader' => false,
Expand Down
17 changes: 13 additions & 4 deletions resources/js/components/OtpDisplay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
const generated_at = ref(null)
const hasTOTP = ref(false)
const showInlineSpinner = ref(false)
const revealPassword = ref(false)
const dots = ref()
const totpLooper = ref()
Expand All @@ -66,6 +67,7 @@
*
*/
const show = async (accountId) => {
revealPassword.value = false
// 3 possible cases :
//
Expand Down Expand Up @@ -225,6 +227,7 @@
}
else if(user.preferences.closeOtpOnCopy && (permit_closing || false) === true) {
emit("please-close-me");
revealPassword.value = false
clearOTP()
}
Expand Down Expand Up @@ -285,17 +288,23 @@
@keyup.enter="copyOTP(password, true)"
:title="$t('commons.copy_to_clipboard')"
>
{{ useDisplayablePassword(password) }}
{{ useDisplayablePassword(password, user.preferences.showOtpAsDot && user.preferences.revealDottedOTP && revealPassword) }}
</span>
<span v-else tabindex="0" class="otp is-size-1">
<Spinner :isVisible="showInlineSpinner" :type="'raw'" />
</span>
</p>
</UseColorMode>
<Dots v-show="isTimeBased(otpauthParams.otp_type)" ref="dots"></Dots>
<ul v-show="isHMacBased(otpauthParams.otp_type)">
<li>counter: {{ otpauthParams.counter }}</li>
</ul>
<p v-show="isHMacBased(otpauthParams.otp_type)">
{{ $t('twofaccounts.forms.counter.label') }}: {{ otpauthParams.counter }}
</p>
<p v-if="user.preferences.showOtpAsDot && user.preferences.revealDottedOTP" class="mt-3">
<button class="button is-ghost has-text-grey-dark" @click.stop="revealPassword = !revealPassword">
<font-awesome-icon v-if="revealPassword" :icon="['fas', 'eye']" />
<font-awesome-icon v-else :icon="['fas', 'eye-slash']" />
</button>
</p>
<TotpLooper
v-if="hasTOTP"
:period="otpauthParams.period"
Expand Down
4 changes: 2 additions & 2 deletions resources/js/composables/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function useIdGenerator(fieldType, fieldName) {
}
}

export function useDisplayablePassword(pwd) {
export function useDisplayablePassword(pwd, reveal = false) {
const user = useUserStore()

if (user.preferences.formatPassword && pwd.length > 0) {
Expand All @@ -48,5 +48,5 @@ export function useDisplayablePassword(pwd) {
}
}

return user.preferences.showOtpAsDot ? pwd.replace(/[0-9]/g, '●') : pwd
return user.preferences.showOtpAsDot && !reveal ? pwd.replace(/[0-9]/g, '●') : pwd
}
2 changes: 2 additions & 0 deletions resources/js/views/settings/Options.vue
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@
<FormCheckbox v-model="user.preferences.copyOtpOnDisplay" @update:model-value="val => savePreference('copyOtpOnDisplay', val)" fieldName="copyOtpOnDisplay" label="settings.forms.copy_otp_on_display.label" help="settings.forms.copy_otp_on_display.help" :isDisabled="!user.preferences.getOtpOnRequest" :isIndented="true" />
<!-- otp as dot -->
<FormCheckbox v-model="user.preferences.showOtpAsDot" @update:model-value="val => savePreference('showOtpAsDot', val)" fieldName="showOtpAsDot" label="settings.forms.show_otp_as_dot.label" help="settings.forms.show_otp_as_dot.help" />
<!-- reveal dotted OTPs -->
<FormCheckbox v-model="user.preferences.revealDottedOTP" @update:model-value="val => savePreference('revealDottedOTP', val)" fieldName="revealDottedOTP" label="settings.forms.reveal_dotted_otp.label" help="settings.forms.reveal_dotted_otp.help" :isDisabled="!user.preferences.showOtpAsDot" :isIndented="true" />
<h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('settings.data_input') }}</h4>
<!-- basic qrcode -->
<FormCheckbox v-model="user.preferences.useBasicQrcodeReader" @update:model-value="val => savePreference('useBasicQrcodeReader', val)" fieldName="useBasicQrcodeReader" label="settings.forms.use_basic_qrcode_reader.label" help="settings.forms.use_basic_qrcode_reader.help" />
Expand Down
13 changes: 12 additions & 1 deletion resources/js/views/twofaccounts/Accounts.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
const isDragging = ref(false)
const isRenewingOTPs = ref(false)
const renewedPeriod = ref(null)
const revealPassword = ref(null)
const otpDisplay = ref(null)
const otpDisplayProps = ref({
Expand Down Expand Up @@ -398,7 +399,7 @@
<FontAwesomeIcon :icon="['fas', 'circle-notch']" spin />
</span>
<span v-else class="always-on-otp is-clickable has-nowrap has-text-grey is-size-5 ml-4" @click="copyToClipboard(account.otp.password)" @keyup.enter="copyToClipboard(account.otp.password)" :title="$t('commons.copy_to_clipboard')">
{{ useDisplayablePassword(account.otp.password) }}
{{ useDisplayablePassword(account.otp.password, user.preferences.showOtpAsDot && user.preferences.revealDottedOTP && revealPassword == account.id) }}
</span>
<Dots
v-if="account.otp_type.includes('totp')"
Expand All @@ -416,6 +417,16 @@
</span>
</div>
</transition>
<transition name="popLater" v-if="user.preferences.showOtpAsDot && user.preferences.revealDottedOTP">
<div v-show="user.preferences.getOtpOnRequest == false && !bus.inManagementMode" class="has-text-right">
<button v-if="revealPassword == account.id" class="pr-0 button is-ghost has-text-grey-dark" @click.stop="revealPassword = null">
<font-awesome-icon :icon="['fas', 'eye']" />
</button>
<button v-else class="pr-0 button is-ghost has-text-grey-dark" @click.stop="revealPassword = account.id">
<font-awesome-icon :icon="['fas', 'eye-slash']" />
</button>
</div>
</transition>
<transition name="fadeInOut">
<div class="tfa-cell tfa-edit has-text-grey" v-if="bus.inManagementMode">
<UseColorMode v-slot="{ mode }">
Expand Down
4 changes: 4 additions & 0 deletions resources/lang/en/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@
'label' => 'Show generated <abbr title="One-Time Password">OTP</abbr> as dot',
'help' => 'Replace generated password caracters with *** to ensure confidentiality. Do not affect the copy/paste feature'
],
'reveal_dotted_otp' => [
'label' => 'Reveal obscured <abbr title="One-Time Password">OTP</abbr>',
'help' => 'Let the ability to temporarily reveal Dot-Obscured passwords'
],
'close_otp_on_copy' => [
'label' => 'Close <abbr title="One-Time Password">OTP</abbr> after copy',
'help' => 'Clicking a generated password to copy it automatically hide it from the screen'
Expand Down
1 change: 1 addition & 0 deletions resources/lang/en/twofaccounts.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
'accounts_deleted' => 'Account(s) successfully deleted',
'accounts_moved' => 'Account(s) successfully moved',
'export_selected_to_json' => 'Download a json export of selected accounts',
'reveal' => 'reveal',
'forms' => [
'service' => [
'placeholder' => 'Google, Twitter, Apple',
Expand Down

0 comments on commit b2e733e

Please sign in to comment.