Start.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <template>
  2. <!-- static landing UI -->
  3. <div class="container has-text-centered">
  4. <div class="columns quick-uploader">
  5. <!-- trailer phrase that invite to add an account -->
  6. <div class="column is-full quick-uploader-header" :class="{ 'is-invisible' : accountCount !== 0 }">
  7. {{ $t('twofaccounts.no_account_here') }}<br>
  8. {{ $t('twofaccounts.add_first_account') }}
  9. </div>
  10. <!-- Livescan button -->
  11. <div class="column is-full quick-uploader-button" >
  12. <div class="quick-uploader-centerer">
  13. <!-- upload a qr code (with basic file field and backend decoding) -->
  14. <label v-if="$root.appSettings.useBasicQrcodeReader" class="button is-link is-medium is-rounded is-focused" ref="qrcodeInputLabel">
  15. <input class="file-input" type="file" accept="image/*" v-on:change="submitQrCode" ref="qrcodeInput">
  16. {{ $t('twofaccounts.forms.upload_qrcode') }}
  17. </label>
  18. <!-- scan button that launch camera stream -->
  19. <label v-else class="button is-link is-medium is-rounded is-focused" @click="capture()">
  20. {{ $t('twofaccounts.forms.scan_qrcode') }}
  21. </label>
  22. </div>
  23. </div>
  24. <!-- alternative methods -->
  25. <div class="column is-full">
  26. <div class="block has-text-light">{{ $t('twofaccounts.forms.alternative_methods') }}</div>
  27. <!-- upload a qr code -->
  28. <div class="block has-text-link" v-if="!$root.appSettings.useBasicQrcodeReader">
  29. <label class="button is-link is-outlined is-rounded" ref="qrcodeInputLabel">
  30. <input class="file-input" type="file" accept="image/*" v-on:change="submitQrCode" ref="qrcodeInput">
  31. {{ $t('twofaccounts.forms.upload_qrcode') }}
  32. </label>
  33. </div>
  34. <!-- link to advanced form -->
  35. <div v-if="showAdvancedFormButton" class="block has-text-link">
  36. <router-link class="button is-link is-outlined is-rounded" :to="{ name: 'createAccount' }" >
  37. {{ $t('twofaccounts.forms.use_advanced_form') }}
  38. </router-link>
  39. </div>
  40. </div>
  41. </div>
  42. <!-- Footer -->
  43. <vue-footer :showButtons="true" >
  44. <!-- back button -->
  45. <p class="control" v-if="accountCount > 0">
  46. <router-link class="button is-dark is-rounded" :to="{ name: returnToView }" >
  47. {{ $t('commons.back') }}
  48. </router-link>
  49. </p>
  50. </vue-footer>
  51. </div>
  52. </template>
  53. <script>
  54. /**
  55. * Start view
  56. *
  57. * route: '/start'
  58. *
  59. * Offer the user all available possibilities for capturing an account :
  60. * - By sending the user to the live scanner
  61. * - By decoding a QR code submitted with a form 'File' field
  62. * - By sending the user to the advanced form
  63. *
  64. */
  65. import Form from './../components/Form'
  66. export default {
  67. name: 'Start',
  68. data(){
  69. return {
  70. accountCount: null,
  71. form: new Form(),
  72. }
  73. },
  74. props: {
  75. showAdvancedFormButton: {
  76. type: Boolean,
  77. default: true
  78. },
  79. returnToView: {
  80. type: String,
  81. default: 'accounts'
  82. },
  83. },
  84. mounted() {
  85. this.axios.get('api/v1/twofaccounts/count').then(response => {
  86. this.accountCount = response.data.count
  87. })
  88. },
  89. created() {
  90. this.$nextTick(() => {
  91. if( this.$root.appSettings.useDirectCapture && this.$root.appSettings.defaultCaptureMode === 'upload' ) {
  92. this.$refs.qrcodeInputLabel.click()
  93. }
  94. })
  95. },
  96. methods: {
  97. /**
  98. * Upload the submitted QR code file to the backend for decoding, then route the user
  99. * to the Create or Import form with decoded URI to prefill the form
  100. */
  101. submitQrCode() {
  102. let imgdata = new FormData();
  103. imgdata.append('qrcode', this.$refs.qrcodeInput.files[0]);
  104. imgdata.append('inputFormat', 'fileUpload');
  105. this.form.upload('/api/v1/qrcode/decode', imgdata, {returnError: true}).then(response => {
  106. if( response.data.data.slice(0, 33).toLowerCase() === "otpauth-migration://offline?data=" ) {
  107. this.$router.push({ name: 'importAccounts', params: { migrationUri: response.data.data } });
  108. }
  109. else this.$router.push({ name: 'createAccount', params: { decodedUri: response.data.data } });
  110. })
  111. .catch(error => {
  112. this.$notify({type: 'is-danger', text: this.$t(error.response.data.message) })
  113. });
  114. },
  115. /**
  116. * Push user to the dedicated capture view for live scan
  117. */
  118. capture() {
  119. this.$router.push({ name: 'capture' });
  120. },
  121. }
  122. };
  123. </script>