Start.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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 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: 'accounts' }" >
  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. mounted() {
  75. this.axios.get('api/v1/twofaccounts/count').then(response => {
  76. this.accountCount = response.data.count
  77. })
  78. },
  79. created() {
  80. this.$nextTick(() => {
  81. if( this.$root.appSettings.useDirectCapture && this.$root.appSettings.defaultCaptureMode === 'upload' ) {
  82. this.$refs.qrcodeInputLabel.click()
  83. }
  84. })
  85. },
  86. methods: {
  87. /**
  88. * Upload the submitted QR code file to the backend for decoding, then route the user
  89. * to the Create or Import form with decoded URI to prefill the form
  90. */
  91. async submitQrCode() {
  92. let imgdata = new FormData();
  93. imgdata.append('qrcode', this.$refs.qrcodeInput.files[0]);
  94. imgdata.append('inputFormat', 'fileUpload');
  95. const { data } = await this.form.upload('/api/v1/qrcode/decode', imgdata)
  96. if( data.data.slice(0, 33).toLowerCase() === "otpauth-migration://offline?data=" ) {
  97. this.$router.push({ name: 'importAccounts', params: { migrationUri: data.data } });
  98. }
  99. else this.$router.push({ name: 'createAccount', params: { decodedUri: data.data } });
  100. },
  101. /**
  102. * Push user to the dedicated capture view for live scan
  103. */
  104. capture() {
  105. this.$router.push({ name: 'capture' });
  106. },
  107. }
  108. };
  109. </script>