ApiToken.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <template>
  2. <div class="mt-6">
  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 New' }} 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 @click="revokeModalOpen = true" class="text-red-500 font-bold focus:outline-none">
  29. Revoke Token
  30. </button>
  31. </div>
  32. <Modal :open="modalOpen" @close="closeModal">
  33. <div class="max-w-lg w-full bg-white rounded-lg shadow-2xl px-6 py-6">
  34. <h2
  35. class="font-semibold text-grey-900 text-2xl leading-tight border-b-2 border-grey-100 pb-4"
  36. >
  37. API Token
  38. </h2>
  39. <p class="my-4 text-grey-700">
  40. This is your new API token. This is the only time the token will ever be displayed, so
  41. please make a note of it in a safe place (e.g. password manager)! You may revoke or rotate
  42. the token at any time from your API settings.
  43. </p>
  44. <pre class="flex p-3 text-grey-900 bg-white border rounded">
  45. <code class="break-all whitespace-normal">{{ token }}</code>
  46. </pre>
  47. <div class="mt-6">
  48. <button
  49. class="bg-cyan-400 hover:bg-cyan-300 text-cyan-900 font-bold py-3 px-4 rounded focus:outline-none"
  50. v-clipboard="() => token"
  51. v-clipboard:success="clipboardSuccess"
  52. v-clipboard:error="clipboardError"
  53. >
  54. Copy To Clipboard
  55. </button>
  56. <button
  57. @click="closeModal"
  58. 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"
  59. >
  60. Close
  61. </button>
  62. </div>
  63. </div>
  64. </Modal>
  65. <Modal :open="revokeModalOpen" @close="closeRevokeModal">
  66. <div class="max-w-lg w-full bg-white rounded-lg shadow-2xl px-6 py-6">
  67. <h2
  68. class="font-semibold text-grey-900 text-2xl leading-tight border-b-2 border-grey-100 pb-4"
  69. >
  70. Revoke API Token
  71. </h2>
  72. <p class="my-4 text-grey-700">
  73. Any browser extension, application or script using this API token will no longer be able
  74. to access the AnonAddy API. This action cannot be undone.
  75. </p>
  76. <div class="mt-6">
  77. <button
  78. @click="revoke"
  79. class="bg-red-500 hover:bg-red-600 text-white font-bold py-3 px-4 rounded focus:outline-none"
  80. :class="revokeLoading ? 'cursor-not-allowed' : ''"
  81. :disabled="revokeLoading"
  82. >
  83. Revoke Token
  84. <loader v-if="revokeLoading" />
  85. </button>
  86. <button
  87. @click="closeRevokeModal"
  88. 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"
  89. >
  90. Close
  91. </button>
  92. </div>
  93. </div>
  94. </Modal>
  95. </div>
  96. </template>
  97. <script>
  98. import Modal from './../components/Modal.vue'
  99. export default {
  100. props: {
  101. initialToken: {
  102. type: String,
  103. required: true,
  104. },
  105. },
  106. components: {
  107. Modal,
  108. },
  109. data() {
  110. return {
  111. loading: false,
  112. revokeLoading: false,
  113. modalOpen: false,
  114. revokeModalOpen: false,
  115. token: this.initialToken,
  116. }
  117. },
  118. methods: {
  119. rotate() {
  120. this.loading = true
  121. axios
  122. .post('/settings/api-token', {
  123. headers: { 'Content-Type': 'application/json' },
  124. })
  125. .then(response => {
  126. this.modalOpen = true
  127. this.loading = false
  128. this.token = response.data.token
  129. })
  130. .catch(error => {
  131. this.loading = false
  132. this.error()
  133. })
  134. },
  135. revoke() {
  136. this.revokeLoading = true
  137. axios
  138. .delete('/settings/api-token', {
  139. headers: { 'Content-Type': 'application/json' },
  140. })
  141. .then(response => {
  142. this.revokeModalOpen = false
  143. this.revokeLoading = false
  144. this.token = ''
  145. this.success('Token Revoked Successfully!')
  146. })
  147. .catch(error => {
  148. this.revokeModalOpen = false
  149. this.revokeLoading = false
  150. this.error()
  151. })
  152. },
  153. closeModal() {
  154. this.modalOpen = false
  155. },
  156. closeRevokeModal() {
  157. this.revokeModalOpen = false
  158. },
  159. clipboardSuccess() {
  160. this.success('Copied to clipboard')
  161. },
  162. clipboardError() {
  163. this.error('Could not copy to clipboard')
  164. },
  165. success(text = '') {
  166. this.$notify({
  167. title: 'Success',
  168. text: text,
  169. type: 'success',
  170. })
  171. },
  172. error(text = 'An error has occurred, please try again later') {
  173. this.$notify({
  174. title: 'Error',
  175. text: text,
  176. type: 'error',
  177. })
  178. },
  179. },
  180. }
  181. </script>