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.

269 lines
9.2 KiB

  1. <template lang='pug'>
  2. v-container(fluid, grid-list-lg)
  3. v-layout(row wrap)
  4. v-flex(xs12)
  5. .admin-header
  6. img.animated.fadeInUp(src='/_assets/svg/icon-validation.svg', alt='SSL', style='width: 80px;')
  7. .admin-header-title
  8. .headline.primary--text.animated.fadeInLeft {{ $t('admin:ssl.title') }}
  9. .subtitle-1.grey--text.animated.fadeInLeft {{ $t('admin:ssl.subtitle') }}
  10. v-spacer
  11. v-btn.animated.fadeInDown(
  12. v-if='info.sslProvider === `letsencrypt` && info.httpsPort > 0'
  13. color='black'
  14. dark
  15. depressed
  16. @click='renewCertificate'
  17. large
  18. :loading='loadingRenew'
  19. )
  20. v-icon(left) mdi-cached
  21. span {{$t('admin:ssl.renewCertificate')}}
  22. v-form.pt-3
  23. v-layout(row wrap)
  24. v-flex(lg6 xs12)
  25. v-card.animated.fadeInUp
  26. v-subheader {{ $t('admin:ssl.currentState') }}
  27. v-list(two-line, dense)
  28. v-list-item
  29. v-list-item-avatar
  30. v-icon.indigo.white--text mdi-handshake
  31. v-list-item-content
  32. v-list-item-title {{ $t(`admin:ssl.provider`) }}
  33. v-list-item-subtitle {{ providerTitle }}
  34. template(v-if='info.sslProvider === `letsencrypt` && info.httpsPort > 0')
  35. v-list-item
  36. v-list-item-avatar
  37. v-icon.indigo.white--text mdi-application
  38. v-list-item-content
  39. v-list-item-title {{ $t(`admin:ssl.domain`) }}
  40. v-list-item-subtitle {{ info.sslDomain }}
  41. v-list-item
  42. v-list-item-avatar
  43. v-icon.indigo.white--text mdi-at
  44. v-list-item-content
  45. v-list-item-title {{ $t('admin:ssl.subscriberEmail') }}
  46. v-list-item-subtitle {{ info.sslSubscriberEmail }}
  47. v-list-item
  48. v-list-item-avatar
  49. v-icon.indigo.white--text mdi-calendar-remove-outline
  50. v-list-item-content
  51. v-list-item-title {{ $t('admin:ssl.expiration') }}
  52. v-list-item-subtitle {{ info.sslExpirationDate | moment('calendar') }}
  53. v-list-item
  54. v-list-item-avatar
  55. v-icon.indigo.white--text mdi-traffic-light
  56. v-list-item-content
  57. v-list-item-title {{ $t(`admin:ssl.status`) }}
  58. v-list-item-subtitle {{ info.sslStatus }}
  59. v-flex(lg6 xs12)
  60. v-card.animated.fadeInUp.wait-p2s
  61. v-subheader {{ $t('admin:ssl.ports') }}
  62. v-list(two-line, dense)
  63. v-list-item
  64. v-list-item-avatar
  65. v-icon.blue.white--text mdi-lock-open-variant
  66. v-list-item-content
  67. v-list-item-title {{ $t(`admin:ssl.httpPort`) }}
  68. v-list-item-subtitle {{ info.httpPort }}
  69. template(v-if='info.httpsPort > 0')
  70. v-divider
  71. v-list-item
  72. v-list-item-avatar
  73. v-icon.green.white--text mdi-lock
  74. v-list-item-content
  75. v-list-item-title {{ $t(`admin:ssl.httpsPort`) }}
  76. v-list-item-subtitle {{ info.httpsPort }}
  77. v-divider
  78. v-list-item
  79. v-list-item-avatar
  80. v-icon.indigo.white--text mdi-sign-direction
  81. v-list-item-content
  82. v-list-item-title {{ $t(`admin:ssl.httpPortRedirect`) }}
  83. v-list-item-subtitle {{ info.httpRedirection }}
  84. v-list-item-action
  85. v-btn.red--text(
  86. v-if='info.httpRedirection'
  87. depressed
  88. :color='$vuetify.theme.dark ? `red darken-4` : `red lighten-5`'
  89. :class='$vuetify.theme.dark ? `text--lighten-5` : `text--darken-2`'
  90. @click='toggleRedir'
  91. :loading='loadingRedir'
  92. )
  93. v-icon(left) mdi-power
  94. span {{$t('admin:ssl.httpPortRedirectTurnOff')}}
  95. v-btn.green--text(
  96. v-else
  97. depressed
  98. :color='$vuetify.theme.dark ? `green darken-4` : `green lighten-5`'
  99. :class='$vuetify.theme.dark ? `text--lighten-5` : `text--darken-2`'
  100. @click='toggleRedir'
  101. :loading='loadingRedir'
  102. )
  103. v-icon(left) mdi-power
  104. span {{$t('admin:ssl.httpPortRedirectTurnOn')}}
  105. v-dialog(
  106. v-model='loadingRenew'
  107. persistent
  108. max-width='450'
  109. )
  110. v-card(color='black', dark)
  111. v-card-text.pa-10.text-center
  112. semipolar-spinner.animated.fadeIn(
  113. :animation-duration='1500'
  114. :size='65'
  115. color='#FFF'
  116. style='margin: 0 auto;'
  117. )
  118. .mt-5.body-1.white--text {{$t('admin:ssl.renewCertificateLoadingTitle')}}
  119. .caption.mt-4 {{$t('admin:ssl.renewCertificateLoadingSubtitle')}}
  120. </template>
  121. <script>
  122. import _ from 'lodash'
  123. import gql from 'graphql-tag'
  124. import { SemipolarSpinner } from 'epic-spinners'
  125. export default {
  126. components: {
  127. SemipolarSpinner
  128. },
  129. data() {
  130. return {
  131. loadingRenew: false,
  132. loadingRedir: false,
  133. info: {
  134. sslDomain: '',
  135. sslProvider: '',
  136. sslSubscriberEmail: '',
  137. sslExpirationDate: false,
  138. sslStatus: '',
  139. httpPort: 0,
  140. httpRedirection: false,
  141. httpsPort: 0
  142. }
  143. }
  144. },
  145. computed: {
  146. providerTitle () {
  147. switch (this.info.sslProvider) {
  148. case 'custom':
  149. return this.$t('admin:ssl.providerCustomCertificate')
  150. case 'letsencrypt':
  151. return this.$t('admin:ssl.providerLetsEncrypt')
  152. default:
  153. return this.$t('admin:ssl.providerDisabled')
  154. }
  155. }
  156. },
  157. methods: {
  158. async toggleRedir () {
  159. this.loadingRedir = true
  160. try {
  161. this.info.httpRedirection = !this.info.httpRedirection
  162. await this.$apollo.mutate({
  163. mutation: gql`
  164. mutation ($enabled: Boolean!) {
  165. system {
  166. setHTTPSRedirection(enabled: $enabled) {
  167. responseResult {
  168. succeeded
  169. errorCode
  170. slug
  171. message
  172. }
  173. }
  174. }
  175. }
  176. `,
  177. variables: {
  178. enabled: _.get(this.info, 'httpRedirection', false)
  179. },
  180. watchLoading (isLoading) {
  181. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-ssl-toggleRedirection')
  182. }
  183. })
  184. this.$store.commit('showNotification', {
  185. style: 'success',
  186. message: this.$t('admin:ssl.httpPortRedirectSaveSuccess'),
  187. icon: 'check'
  188. })
  189. } catch (err) {
  190. this.info.httpRedirection = !this.info.httpRedirection
  191. this.$store.commit('pushGraphError', err)
  192. }
  193. this.loadingRedir = false
  194. },
  195. async renewCertificate () {
  196. this.loadingRenew = true
  197. try {
  198. const respRaw = await this.$apollo.mutate({
  199. mutation: gql`
  200. mutation {
  201. system {
  202. renewHTTPSCertificate {
  203. responseResult {
  204. succeeded
  205. errorCode
  206. slug
  207. message
  208. }
  209. }
  210. }
  211. }
  212. `,
  213. watchLoading (isLoading) {
  214. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-ssl-renew')
  215. }
  216. })
  217. const resp = _.get(respRaw, 'data.system.renewHTTPSCertificate.responseResult', {})
  218. if (resp.succeeded) {
  219. this.$store.commit('showNotification', {
  220. style: 'success',
  221. message: this.$t('admin:ssl.renewCertificateSuccess'),
  222. icon: 'check'
  223. })
  224. } else {
  225. throw new Error(resp.message)
  226. }
  227. } catch (err) {
  228. this.$store.commit('pushGraphError', err)
  229. }
  230. this.loadingRenew = false
  231. }
  232. },
  233. apollo: {
  234. info: {
  235. query: gql`
  236. {
  237. system {
  238. info {
  239. httpPort
  240. httpRedirection
  241. httpsPort
  242. sslDomain
  243. sslExpirationDate
  244. sslProvider
  245. sslStatus
  246. sslSubscriberEmail
  247. }
  248. }
  249. }
  250. `,
  251. fetchPolicy: 'network-only',
  252. update: (data) => _.cloneDeep(data.system.info),
  253. watchLoading (isLoading) {
  254. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-ssl-refresh')
  255. }
  256. }
  257. }
  258. }
  259. </script>
  260. <style lang='scss'>
  261. </style>