Bläddra i källkod

Add user option to automatically copy OTP on display - Close #125

Bubka 2 år sedan
förälder
incheckning
3d75ccc1fc

+ 1 - 0
config/2fauth.php

@@ -48,6 +48,7 @@ return [
     'options' => [
         'showTokenAsDot' => false,
         'closeOtpOnCopy' => false,
+        'copyOtpOnDisplay' => false,
         'useBasicQrcodeReader' => false,
         'displayMode' => 'list',
         'showAccountsIcons' => true,

+ 51 - 19
resources/js/components/OtpDisplayer.vue

@@ -143,30 +143,50 @@
             getOtp: async function() {
 
                 try {
+                    let request, password
+
                     if(this.internal_id) {
-                        const { data } =  await this.axios.get('/api/v1/twofaccounts/' + this.internal_id + '/otp')
-                        return data
+                        request = {
+                            method: 'get',
+                            url: '/api/v1/twofaccounts/' + this.internal_id + '/otp'
+                        }
                     }
                     else if(this.internal_uri) {
-                        const { data } =  await this.axios.post('/api/v1/twofaccounts/otp', {
-                            uri: this.internal_uri
-                        })
-                        return data
+                        request = {
+                            method: 'post',
+                            url: '/api/v1/twofaccounts/otp',
+                            data: {
+                                uri: this.internal_uri
+                            }
+                        }
                     }
                     else {
-                        const { data } =  await this.axios.post('/api/v1/twofaccounts/otp', {
-                            service     : this.internal_service,
-                            account     : this.internal_account,
-                            icon        : this.internal_icon,
-                            otp_type    : this.internal_otp_type,
-                            secret      : this.internal_secret,
-                            digits      : this.internal_digits,
-                            algorithm   : this.internal_algorithm,
-                            period      : this.internal_period,
-                            counter     : this.internal_counter,
-                        })
-                        return data
+                        request = {
+                            method: 'post',
+                            url: '/api/v1/twofaccounts/otp',
+                            data: {
+                                service     : this.internal_service,
+                                account     : this.internal_account,
+                                icon        : this.internal_icon,
+                                otp_type    : this.internal_otp_type,
+                                secret      : this.internal_secret,
+                                digits      : this.internal_digits,
+                                algorithm   : this.internal_algorithm,
+                                period      : this.internal_period,
+                                counter     : this.internal_counter,
+                            }
+                        }
                     }
+
+                    await this.axios(request).then(response => {
+                        if(this.$root.appSettings.copyOtpOnDisplay) {
+                            this.copyAndNotify(response.data.password)
+                        }
+                        password = response.data
+                    })
+
+                    return password
+
                 }
                 catch(error) {
                     if (error.response.status === 422) {
@@ -182,6 +202,7 @@
 
                 this.internal_password = otp.password
                 this.internal_otp_type = otp.otp_type
+
                 let generated_at = otp.generated_at
                 let period = otp.period
 
@@ -314,7 +335,18 @@
 
             clipboardErrorHandler ({ value, event }) {
                 console.log('error', value)
-            }
+            },
+
+            copyAndNotify (strToCopy) {
+                // see https://web.dev/async-clipboard/ for futur Clipboard API usage.
+                // The API should allow to copy the password on each trip without user interaction.
+
+                // For now too many browsers don't support the clipboard-write permission
+                // (see https://developer.mozilla.org/en-US/docs/Web/API/Permissions#browser_support)
+
+                this.$clipboard(strToCopy)
+                this.$notify({ type: 'is-success', text: this.$t('commons.copied_to_clipboard') })
+            },
 
         },
 

+ 4 - 0
resources/js/views/settings/Options.vue

@@ -32,6 +32,9 @@
                     <form-checkbox v-on:showOtpAsDot="saveSetting('showOtpAsDot', $event)" :form="form" fieldName="showOtpAsDot" :label="$t('settings.forms.show_otp_as_dot.label')" :help="$t('settings.forms.show_otp_as_dot.help')" />
                     <!-- close otp on copy -->
                     <form-checkbox v-on:closeOtpOnCopy="saveSetting('closeOtpOnCopy', $event)" :form="form" fieldName="closeOtpOnCopy" :label="$t('settings.forms.close_otp_on_copy.label')" :help="$t('settings.forms.close_otp_on_copy.help')" />
+                    <!-- copy otp on get -->
+                    <form-checkbox v-on:copyOtpOnDisplay="saveSetting('copyOtpOnDisplay', $event)" :form="form" fieldName="copyOtpOnDisplay" :label="$t('settings.forms.copy_otp_on_display.label')" :help="$t('settings.forms.copy_otp_on_display.help')" />
+
 
                     <h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('settings.data_input') }}</h4>
                     <!-- basic qrcode -->
@@ -81,6 +84,7 @@
                     lang: 'browser',
                     showOtpAsDot: null,
                     closeOtpOnCopy: null,
+                    copyOtpOnDisplay: null,
                     useBasicQrcodeReader: null,
                     showAccountsIcons: null,
                     displayMode: '',

+ 6 - 2
resources/lang/en/settings.php

@@ -50,11 +50,15 @@ return [
         ],
         'show_otp_as_dot' => [
             'label' => 'Show generated one-time passwords as dot',
-            'help' => 'Replace generated password caracters with *** to ensure confidentiality. Do not affect the copy/paste feature.'
+            'help' => 'Replace generated password caracters with *** to ensure confidentiality. Do not affect the copy/paste feature'
         ],
         'close_otp_on_copy' => [
             'label' => 'Close OTP after copy',
-            'help' => 'Automatically close the popup showing the generated password after it has been copied'
+            'help' => 'Clicking a generated password to copy it automatically hide it from the screen'
+        ],
+        'copy_otp_on_display' => [
+            'label' => 'Copy OTP on display',
+            'help' => 'Automatically copy a generated password right after it appears on screen. Due to browsers limitations, only the first TOTP password will be copied, not the rotating ones'
         ],
         'use_basic_qrcode_reader' => [
             'label' => 'Use basic QR code reader',

+ 9 - 5
resources/lang/fr/settings.php

@@ -46,15 +46,19 @@ return [
         'help_translate_2fauth' => 'Aidez à traduire 2FAuth',
         'language' => [
             'label' => 'Langue',
-            'help' => 'Langue utilisée pour traduire l\'interface utilisateur de 2FAuth. Les langues proposées sont complètes, vous pouvez les utiliser pour remplacer la langue de référence de votre navigateur.'
+            'help' => 'Langue utilisée pour traduire l\'interface utilisateur de 2FAuth. Les langues proposées sont complètes, vous pouvez les utiliser pour remplacer la langue de référence de votre navigateur'
         ],
         'show_otp_as_dot' => [
-            'label' => 'Afficher les mots de passe générés sous forme de point',
-            'help' => 'Remplace les caractères des mots de passe générés par des ●●● pour garantir leur confidentialité. N\'affecte pas la fonction de copier/coller qui reste utilisable.'
+            'label' => 'Masquer les mots de passe',
+            'help' => 'Remplace les caractères des mots de passe générés par des ●●● pour garantir leur confidentialité. N\'affecte pas la fonction de copier/coller qui reste utilisable'
         ],
         'close_otp_on_copy' => [
-            'label' => 'Ne plus afficher les mots de passe copiés',
-            'help' => 'Ferme automatiquement le popup affichant le mot de passe généré dès que ce dernier a été copié'
+            'label' => 'Cacher les mots de passe copiés',
+            'help' => 'Les mots de passe qui viennent d\'être copiés via un click ne restent pas visibles à l\'écran'
+        ],
+        'copy_otp_on_display' => [
+            'label' => 'Copier le mot de passe dès qu\'il s\'affiche',
+            'help' => 'Copie automatiquement dans le presse-papier un mot de passe qui vient de s\'afficher à l\'écran. A cause de restrictions des navigateurs, seul le premier mot de passe TOTP à s\'afficher est copié, pas les mots de passe successifs.'
         ],
         'use_basic_qrcode_reader' => [
             'label' => 'Utiliser le lecteur de QR code basique',