You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PersonalSettings.vue 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <template>
  2. <div>
  3. <button v-if="!enabled"
  4. id="generate-backup-codes"
  5. :disabled="generatingCodes"
  6. @click="generateBackupCodes">
  7. {{ t('twofactor_backupcodes', 'Generate backup codes') }}
  8. <span :class="{'icon-loading-small': generatingCodes}" />
  9. </button>
  10. <template v-else>
  11. <p>
  12. <template v-if="!haveCodes">
  13. {{ t('twofactor_backupcodes', 'Backup codes have been generated. {used} of {total} codes have been used.', {used, total}) }}
  14. </template>
  15. <template v-else>
  16. {{ t('twofactor_backupcodes', 'These are your backup codes. Please save and/or print them as you will not be able to read the codes again later') }}
  17. <ul>
  18. <li v-for="code in codes" :key="code" class="backup-code">
  19. {{ code }}
  20. </li>
  21. </ul>
  22. <a :href="downloadUrl"
  23. class="button primary"
  24. :download="downloadFilename">{{ t('twofactor_backupcodes', 'Save backup codes') }}</a>
  25. <button class="button"
  26. @click="printCodes">
  27. {{ t('twofactor_backupcodes', 'Print backup codes') }}
  28. </button>
  29. </template>
  30. </p>
  31. <p>
  32. <button id="generate-backup-codes"
  33. @click="generateBackupCodes">
  34. {{ t('twofactor_backupcodes', 'Regenerate backup codes') }}
  35. </button>
  36. </p>
  37. <p>
  38. <em>
  39. {{ t('twofactor_backupcodes', 'If you regenerate backup codes, you automatically invalidate old codes.') }}
  40. </em>
  41. </p>
  42. </template>
  43. </div>
  44. </template>
  45. <script>
  46. import confirmPassword from 'nextcloud-password-confirmation'
  47. import { print } from '../service/PrintService'
  48. export default {
  49. name: 'PersonalSettings',
  50. data() {
  51. return {
  52. generatingCodes: false,
  53. }
  54. },
  55. computed: {
  56. downloadUrl: function() {
  57. if (!this.codes) {
  58. return ''
  59. }
  60. return 'data:text/plain,' + encodeURIComponent(this.codes.reduce((prev, code) => {
  61. return prev + code + '\r\n'
  62. }, ''))
  63. },
  64. downloadFilename: function() {
  65. const name = OC.theme.name || 'Nextcloud'
  66. return name + '-backup-codes.txt'
  67. },
  68. enabled: function() {
  69. return this.$store.state.enabled
  70. },
  71. total: function() {
  72. return this.$store.state.total
  73. },
  74. used: function() {
  75. return this.$store.state.used
  76. },
  77. codes: function() {
  78. return this.$store.state.codes
  79. },
  80. name: function() {
  81. return OC.theme.name || 'Nextcloud'
  82. },
  83. haveCodes() {
  84. return this.codes && this.codes.length > 0
  85. },
  86. },
  87. methods: {
  88. generateBackupCodes: function() {
  89. confirmPassword().then(() => {
  90. // Hide old codes
  91. this.generatingCodes = true
  92. this.$store.dispatch('generate').then(data => {
  93. this.generatingCodes = false
  94. }).catch(err => {
  95. OC.Notification.showTemporary(t('twofactor_backupcodes', 'An error occurred while generating your backup codes'))
  96. this.generatingCodes = false
  97. throw err
  98. })
  99. }).catch(console.error.bind(this))
  100. },
  101. getPrintData: function(codes) {
  102. if (!codes) {
  103. return ''
  104. }
  105. return codes.reduce((prev, code) => {
  106. return prev + code + '<br>'
  107. }, '')
  108. },
  109. printCodes: function() {
  110. print(this.getPrintData(this.codes))
  111. },
  112. },
  113. }
  114. </script>
  115. <style scoped>
  116. .backup-code {
  117. font-family: monospace;
  118. letter-spacing: 0.02em;
  119. font-size: 1.2em;
  120. }
  121. .button {
  122. display: inline-block;
  123. }
  124. </style>