mirror of
https://github.com/Bubka/2FAuth.git
synced 2025-04-10 10:38:39 +02:00
Show actions instead of error when QR code is not a valid otp auth uri
This commit is contained in:
parent
7efa86b232
commit
3edacf0824
@ -25,6 +25,19 @@ Vue.mixin({
|
|||||||
this.$notify({ clean: true })
|
this.$notify({ clean: true })
|
||||||
this.$router.push({ name: 'accounts' })
|
this.$router.push({ name: 'accounts' })
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isUrl: function (url) {
|
||||||
|
var strRegex = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/
|
||||||
|
var re = new RegExp(strRegex)
|
||||||
|
|
||||||
|
return re.test(url)
|
||||||
|
},
|
||||||
|
|
||||||
|
openInBrowser(uri) {
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.setAttribute('href', uri)
|
||||||
|
a.dispatchEvent(new MouseEvent("click", {'view': window, 'bubbles': true, 'cancelable': true}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +131,26 @@
|
|||||||
</otp-displayer>
|
</otp-displayer>
|
||||||
</modal>
|
</modal>
|
||||||
</form-wrapper>
|
</form-wrapper>
|
||||||
|
<!-- alternatives -->
|
||||||
|
<modal v-model="showAlternatives">
|
||||||
|
<div class="too-bad"></div>
|
||||||
|
<div class="block">
|
||||||
|
{{ $t('errors.data_of_qrcode_is_not_valid_URI') }}
|
||||||
|
</div>
|
||||||
|
<div class="block has-text-light mb-6" v-html="uri"></div>
|
||||||
|
<!-- Copy to clipboard -->
|
||||||
|
<div class="block has-text-link">
|
||||||
|
<label class="button is-link is-outlined is-rounded" v-clipboard="() => uri" v-clipboard:success="clipboardSuccessHandler">
|
||||||
|
{{ $t('commons.copy_to_clipboard') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<!-- Open in browser -->
|
||||||
|
<div class="block has-text-link" v-if="isUrl(uri)" @click="openInBrowser(uri)">
|
||||||
|
<label class="button is-link is-outlined is-rounded">
|
||||||
|
{{ $t('commons.open_in_browser') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -163,7 +183,9 @@
|
|||||||
showQuickForm: false,
|
showQuickForm: false,
|
||||||
showAdvancedForm: false,
|
showAdvancedForm: false,
|
||||||
ShowTwofaccountInModal : false,
|
ShowTwofaccountInModal : false,
|
||||||
|
showAlternatives : false,
|
||||||
tempIcon: '',
|
tempIcon: '',
|
||||||
|
uri: '',
|
||||||
form: new Form({
|
form: new Form({
|
||||||
service: '',
|
service: '',
|
||||||
account: '',
|
account: '',
|
||||||
@ -212,9 +234,10 @@
|
|||||||
|
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
if( this.$route.params.decodedUri ) {
|
if( this.$route.params.decodedUri ) {
|
||||||
|
this.uri = this.$route.params.decodedUri
|
||||||
|
|
||||||
// the Start view provided an uri so we parse it and prefill the quick form
|
// the Start view provided an uri so we parse it and prefill the quick form
|
||||||
this.axios.post('/api/v1/twofaccounts/preview', { uri: this.$route.params.decodedUri }).then(response => {
|
this.axios.post('/api/v1/twofaccounts/preview', { uri: this.uri }).then(response => {
|
||||||
|
|
||||||
this.form.fill(response.data)
|
this.form.fill(response.data)
|
||||||
this.tempIcon = response.data.icon ? response.data.icon : null
|
this.tempIcon = response.data.icon ? response.data.icon : null
|
||||||
@ -222,19 +245,22 @@
|
|||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
if( error.response.status === 422 ) {
|
if( error.response.status === 422 ) {
|
||||||
|
if( error.response.data.errors.uri ) {
|
||||||
this.$router.push({ name: 'genericError', params: { err: this.$t('errors.cannot_create_otp_with_those_parameters') } });
|
this.showAlternatives = true
|
||||||
|
this.showAdvancedForm = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.showAdvancedForm = true
|
this.showAdvancedForm = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop TOTP generation on modal close
|
|
||||||
this.$on('modalClose', function() {
|
this.$on('modalClose', function() {
|
||||||
|
this.showAlternatives = false;
|
||||||
|
|
||||||
this.$refs.AdvancedFormOtpDisplayer.stopLoop()
|
if( this.showAdvancedForm ) {
|
||||||
|
this.$refs.AdvancedFormOtpDisplayer.stopLoop()
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -283,6 +309,7 @@
|
|||||||
|
|
||||||
// First we get the uri encoded in the qrcode
|
// First we get the uri encoded in the qrcode
|
||||||
const { data } = await this.form.upload('/api/v1/qrcode/decode', imgdata)
|
const { data } = await this.form.upload('/api/v1/qrcode/decode', imgdata)
|
||||||
|
this.uri = data.data
|
||||||
|
|
||||||
// Then the otp described by the uri
|
// Then the otp described by the uri
|
||||||
this.axios.post('/api/v1/twofaccounts/preview', { uri: data.data }).then(response => {
|
this.axios.post('/api/v1/twofaccounts/preview', { uri: data.data }).then(response => {
|
||||||
@ -290,6 +317,13 @@
|
|||||||
this.form.secretIsBase32Encoded = 1
|
this.form.secretIsBase32Encoded = 1
|
||||||
this.tempIcon = response.data.icon ? response.data.icon : null
|
this.tempIcon = response.data.icon ? response.data.icon : null
|
||||||
})
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if( error.response.status === 422 ) {
|
||||||
|
if( error.response.data.errors.uri ) {
|
||||||
|
this.showAlternatives = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async uploadIcon(event) {
|
async uploadIcon(event) {
|
||||||
@ -320,6 +354,19 @@
|
|||||||
// is acceptable (and HOTP counter can be edited by the way)
|
// is acceptable (and HOTP counter can be edited by the way)
|
||||||
this.form.counter = payload.nextHotpCounter
|
this.form.counter = payload.nextHotpCounter
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clipboardSuccessHandler ({ value, event }) {
|
||||||
|
|
||||||
|
if(this.$root.appSettings.kickUserAfter == -1) {
|
||||||
|
this.appLogout()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$notify({ type: 'is-success', text: this.$t('commons.copied_to_clipboard') })
|
||||||
|
},
|
||||||
|
|
||||||
|
clipboardErrorHandler ({ value, event }) {
|
||||||
|
console.log('error', value)
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -38,4 +38,5 @@
|
|||||||
'reload' => 'Reload',
|
'reload' => 'Reload',
|
||||||
'some_data_have_changed' => 'Some data have changed. You should',
|
'some_data_have_changed' => 'Some data have changed. You should',
|
||||||
'generate' => 'Generate',
|
'generate' => 'Generate',
|
||||||
|
'open_in_browser' => 'Open in browser',
|
||||||
];
|
];
|
@ -22,7 +22,7 @@
|
|||||||
'Unable_to_decrypt_uri' => 'Unable to decrypt uri',
|
'Unable_to_decrypt_uri' => 'Unable to decrypt uri',
|
||||||
'not_a_supported_otp_type' => 'This OTP format is not currently supported',
|
'not_a_supported_otp_type' => 'This OTP format is not currently supported',
|
||||||
'cannot_create_otp_without_secret' => 'Cannot create an OTP without a secret',
|
'cannot_create_otp_without_secret' => 'Cannot create an OTP without a secret',
|
||||||
'cannot_create_otp_with_those_parameters' => 'Cannot create an OTP with those parameters',
|
'data_of_qrcode_is_not_valid_URI' => 'The data of this QR code is not a valid OTP Auth URI:',
|
||||||
'wrong_current_password' => 'Wrong current password, nothing has changed',
|
'wrong_current_password' => 'Wrong current password, nothing has changed',
|
||||||
'error_during_encryption' => 'Encryption failed, your database remains unprotected.',
|
'error_during_encryption' => 'Encryption failed, your database remains unprotected.',
|
||||||
'error_during_decryption' => 'Decryption failed, your database is still protected. This is mainly caused by an integrity issue of encrypted data for one or more accounts.',
|
'error_during_decryption' => 'Decryption failed, your database is still protected. This is mainly caused by an integrity issue of encrypted data for one or more accounts.',
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user