AuthSettings.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <script setup lang="tsx">
  2. import { message } from 'ant-design-vue'
  3. import type { Ref } from 'vue'
  4. import { inject } from 'vue'
  5. import dayjs from 'dayjs'
  6. import type { BannedIP } from '@/api/settings'
  7. import setting from '@/api/settings'
  8. import type { customRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
  9. import type { Settings } from '@/views/preference/typedef'
  10. const data: Settings = inject('data') as Settings
  11. const bannedIPColumns = [{
  12. title: $gettext('IP'),
  13. dataIndex: 'ip',
  14. }, {
  15. title: $gettext('Attempts'),
  16. dataIndex: 'attempts',
  17. }, {
  18. title: $gettext('Banned Until'),
  19. dataIndex: 'expired_at',
  20. customRender: (args: customRender) => {
  21. return dayjs.unix(args.text).format('YYYY-MM-DD HH:mm:ss')
  22. },
  23. }, {
  24. title: $gettext('Action'),
  25. dataIndex: 'action',
  26. }]
  27. const bannedIPs: Ref<BannedIP[]> = ref([])
  28. function getBannedIPs() {
  29. setting.get_banned_ips().then(r => {
  30. bannedIPs.value = r
  31. })
  32. }
  33. getBannedIPs()
  34. defineExpose({
  35. getBannedIPs,
  36. })
  37. function removeBannedIP(ip: string) {
  38. setting.remove_banned_ip(ip).then(() => {
  39. bannedIPs.value = bannedIPs.value.filter(v => v.ip !== ip)
  40. message.success($gettext('Remove successfully'))
  41. }).catch((e: { message?: string }) => {
  42. message.error(e?.message ?? $gettext('Server error'))
  43. })
  44. }
  45. </script>
  46. <template>
  47. <div class="flex justify-center">
  48. <div>
  49. <AAlert
  50. class="mb-4"
  51. :message="$gettext('Tips')"
  52. :description="$gettext('If the number of login failed attempts from a ip reach the max attempts in ban threshold minutes,'
  53. + ' the ip will be banned for a period of time.')"
  54. type="info"
  55. />
  56. <AForm
  57. layout="horizontal"
  58. style="width:90%;max-width: 500px"
  59. >
  60. <AFormItem :label="$gettext('Ban Threshold Minutes')">
  61. <AInputNumber
  62. v-model:value="data.auth.ban_threshold_minutes"
  63. min="1"
  64. />
  65. </AFormItem>
  66. <AFormItem :label="$gettext('Max Attempts')">
  67. <AInputNumber
  68. v-model:value="data.auth.max_attempts"
  69. min="1"
  70. />
  71. </AFormItem>
  72. </AForm>
  73. <h3>
  74. {{ $gettext('Banned IPs') }}
  75. </h3>
  76. <div class="mb-6">
  77. <ATable
  78. :columns="bannedIPColumns"
  79. row-key="ip"
  80. :data-source="bannedIPs"
  81. size="small"
  82. >
  83. <template #bodyCell="{ column, record }">
  84. <template v-if="column.dataIndex === 'action'">
  85. <APopconfirm
  86. :title="$gettext('Are you sure to delete this banned IP immediately?')"
  87. :ok-text="$gettext('Yes')"
  88. :cancel-text="$gettext('No')"
  89. placement="bottom"
  90. @confirm="() => removeBannedIP(record.ip)"
  91. >
  92. <a>
  93. {{ $gettext('Remove') }}
  94. </a>
  95. </APopconfirm>
  96. </template>
  97. </template>
  98. </ATable>
  99. </div>
  100. </div>
  101. </div>
  102. </template>
  103. <style lang="less" scoped>
  104. </style>