ApiToken.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <template>
  2. <div>
  3. <h3 class="font-bold text-xl">{{ token ? 'Rotate' : 'Generate' }} API Token</h3>
  4. <div class="my-4 w-24 border-b-2 border-grey-200"></div>
  5. <p v-if="token" class="my-6">
  6. To rotate your current API token simply click the button below.
  7. </p>
  8. <p v-else class="my-6">
  9. To enable the use of the API simply click the button below to generate an API token.
  10. </p>
  11. <button
  12. @click="rotate"
  13. class="bg-cyan-400 w-full hover:bg-cyan-300 text-cyan-900 font-bold py-3 px-4 rounded focus:outline-none"
  14. :class="loading ? 'cursor-not-allowed' : ''"
  15. :disabled="loading"
  16. >
  17. {{ token ? 'Rotate' : 'Generate' }} Token
  18. <loader v-if="loading" />
  19. </button>
  20. <div class="mt-6" v-if="token">
  21. <h3 class="font-bold text-xl">
  22. Revoke API Token
  23. </h3>
  24. <div class="my-4 w-24 border-b-2 border-grey-200"></div>
  25. <p class="my-6">
  26. To revoke the current API token simply click the button below.
  27. </p>
  28. <button
  29. @click="revoke"
  30. class="text-red-500 font-bold focus:outline-none"
  31. :class="revokeLoading ? 'cursor-not-allowed' : ''"
  32. :disabled="revokeLoading"
  33. >
  34. Revoke Token
  35. </button>
  36. </div>
  37. <Modal :open="modalOpen" @close="closeModal">
  38. <div class="max-w-lg w-full bg-white rounded-lg shadow-2xl px-6 py-6">
  39. <h2
  40. class="font-semibold text-grey-900 text-2xl leading-tight border-b-2 border-grey-100 pb-4"
  41. >
  42. API Token
  43. </h2>
  44. <p class="my-4 text-grey-700">
  45. This is your new API token. This is the only time the token will ever be displayed, so
  46. please make a note of it in a safe place (e.g. password manager)! You may revoke or rotate
  47. the token at any time from your API settings.
  48. </p>
  49. <pre class="flex p-3 text-grey-900 bg-white border rounded">
  50. <code class="break-all whitespace-normal">{{ token }}</code>
  51. </pre>
  52. <div class="mt-6">
  53. <button
  54. class="bg-cyan-400 hover:bg-cyan-300 text-cyan-900 font-bold py-3 px-4 rounded focus:outline-none"
  55. v-clipboard="() => token"
  56. v-clipboard:success="clipboardSuccess"
  57. v-clipboard:error="clipboardError"
  58. >
  59. Copy To Clipboard
  60. </button>
  61. <button
  62. @click="closeModal"
  63. class="ml-4 px-4 py-3 text-grey-800 font-semibold bg-white hover:bg-grey-50 border border-grey-100 rounded focus:outline-none"
  64. >
  65. Close
  66. </button>
  67. </div>
  68. </div>
  69. </Modal>
  70. </div>
  71. </template>
  72. <script>
  73. import Modal from './../components/Modal.vue'
  74. export default {
  75. props: {
  76. initialToken: {
  77. type: String,
  78. required: true,
  79. },
  80. },
  81. components: {
  82. Modal,
  83. },
  84. data() {
  85. return {
  86. loading: false,
  87. revokeLoading: false,
  88. modalOpen: false,
  89. token: this.initialToken,
  90. }
  91. },
  92. methods: {
  93. rotate() {
  94. this.loading = true
  95. axios
  96. .post('/settings/api-token', {
  97. headers: { 'Content-Type': 'application/json' },
  98. })
  99. .then(response => {
  100. this.modalOpen = true
  101. this.loading = false
  102. this.token = response.data.token
  103. })
  104. .catch(error => {
  105. this.loading = false
  106. this.error()
  107. })
  108. },
  109. revoke() {
  110. this.revokeLoading = true
  111. axios
  112. .delete('/settings/api-token', {
  113. headers: { 'Content-Type': 'application/json' },
  114. })
  115. .then(response => {
  116. this.revokeLoading = false
  117. this.token = ''
  118. this.success('Token Revoked Successfully!')
  119. })
  120. .catch(error => {
  121. this.revokeLoading = false
  122. this.error()
  123. })
  124. },
  125. closeModal() {
  126. this.modalOpen = false
  127. },
  128. clipboardSuccess() {
  129. this.success('Copied to clipboard')
  130. },
  131. clipboardError() {
  132. this.error('Could not copy to clipboard')
  133. },
  134. success(text = '') {
  135. this.$notify({
  136. title: 'Success',
  137. text: text,
  138. type: 'success',
  139. })
  140. },
  141. error(text = 'An error has occurred, please try again later') {
  142. this.$notify({
  143. title: 'Error',
  144. text: text,
  145. type: 'error',
  146. })
  147. },
  148. },
  149. }
  150. </script>