mihari 5.2.4 → 5.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/README.md +0 -10
  4. data/Rakefile +13 -1
  5. data/build_frontend.sh +1 -1
  6. data/frontend/.eslintrc.cjs +22 -0
  7. data/frontend/.gitignore +18 -12
  8. data/frontend/.prettierrc.json +8 -0
  9. data/frontend/env.d.ts +5 -0
  10. data/frontend/package-lock.json +5213 -9655
  11. data/frontend/package.json +38 -25
  12. data/frontend/src/App.vue +5 -5
  13. data/frontend/src/api-helper.ts +38 -40
  14. data/frontend/src/api.ts +40 -40
  15. data/frontend/src/components/ErrorMessage.vue +8 -8
  16. data/frontend/src/components/Loading.vue +4 -4
  17. data/frontend/src/components/Navbar.vue +10 -27
  18. data/frontend/src/components/Pagination.vue +35 -42
  19. data/frontend/src/components/alert/Alert.vue +22 -27
  20. data/frontend/src/components/alert/Alerts.vue +23 -25
  21. data/frontend/src/components/alert/AlertsWithPagination.vue +34 -34
  22. data/frontend/src/components/alert/AlertsWrapper.vue +43 -50
  23. data/frontend/src/components/alert/Form.vue +39 -40
  24. data/frontend/src/components/artifact/AS.vue +7 -7
  25. data/frontend/src/components/artifact/Artifact.vue +69 -86
  26. data/frontend/src/components/artifact/ArtifactTag.vue +21 -27
  27. data/frontend/src/components/artifact/ArtifactTags.vue +8 -8
  28. data/frontend/src/components/artifact/ArtifactWrapper.vue +22 -25
  29. data/frontend/src/components/artifact/CPEs.vue +6 -6
  30. data/frontend/src/components/artifact/DnsRecords.vue +9 -9
  31. data/frontend/src/components/artifact/Ports.vue +6 -6
  32. data/frontend/src/components/artifact/ReverseDnsNames.vue +7 -7
  33. data/frontend/src/components/artifact/Tags.vue +6 -6
  34. data/frontend/src/components/artifact/WhoisRecord.vue +7 -9
  35. data/frontend/src/components/config/Configs.vue +9 -12
  36. data/frontend/src/components/config/ConfigsWrapper.vue +14 -20
  37. data/frontend/src/components/link/Link.vue +7 -7
  38. data/frontend/src/components/link/Links.vue +16 -21
  39. data/frontend/src/components/rule/EditRule.vue +23 -23
  40. data/frontend/src/components/rule/EditRuleWrapper.vue +22 -28
  41. data/frontend/src/components/rule/Form.vue +28 -28
  42. data/frontend/src/components/rule/InputForm.vue +31 -25
  43. data/frontend/src/components/rule/NewRule.vue +19 -19
  44. data/frontend/src/components/rule/Rule.vue +28 -30
  45. data/frontend/src/components/rule/RuleWrapper.vue +24 -31
  46. data/frontend/src/components/rule/Rules.vue +26 -30
  47. data/frontend/src/components/rule/RulesWrapper.vue +40 -43
  48. data/frontend/src/components/rule/YAML.vue +19 -22
  49. data/frontend/src/components/tag/Tag.vue +24 -32
  50. data/frontend/src/components/tag/Tags.vue +11 -11
  51. data/frontend/src/countries.ts +23 -23
  52. data/frontend/src/index.ts +9 -12
  53. data/frontend/src/links/anyrun.ts +10 -10
  54. data/frontend/src/links/base.ts +3 -3
  55. data/frontend/src/links/censys.ts +10 -10
  56. data/frontend/src/links/crtsh.ts +10 -10
  57. data/frontend/src/links/dnslytics.ts +18 -18
  58. data/frontend/src/links/greynoise.ts +10 -10
  59. data/frontend/src/links/index.ts +15 -15
  60. data/frontend/src/links/intezer.ts +10 -10
  61. data/frontend/src/links/otx.ts +14 -14
  62. data/frontend/src/links/securitytrails.ts +15 -15
  63. data/frontend/src/links/shodan.ts +10 -10
  64. data/frontend/src/links/urlscan.ts +19 -19
  65. data/frontend/src/links/virustotal.ts +27 -27
  66. data/frontend/src/main.ts +38 -8
  67. data/frontend/src/router/index.ts +20 -20
  68. data/frontend/src/rule.ts +6 -6
  69. data/frontend/src/shims-vue.d.ts +2 -2
  70. data/frontend/src/types.ts +91 -91
  71. data/frontend/src/utils.ts +23 -29
  72. data/frontend/src/views/Alerts.vue +7 -7
  73. data/frontend/src/views/Artifact.vue +17 -17
  74. data/frontend/src/views/Configs.vue +7 -7
  75. data/frontend/src/views/EditRule.vue +17 -17
  76. data/frontend/src/views/NewRule.vue +10 -10
  77. data/frontend/src/views/Rule.vue +17 -17
  78. data/frontend/src/views/Rules.vue +7 -7
  79. data/frontend/tests/utils.spec.ts +9 -0
  80. data/frontend/tsconfig.app.json +21 -0
  81. data/frontend/tsconfig.json +10 -36
  82. data/frontend/tsconfig.node.json +13 -0
  83. data/frontend/tsconfig.vitest.json +12 -0
  84. data/frontend/vite.config.ts +24 -0
  85. data/frontend/vitest.config.ts +21 -0
  86. data/lefthook.yml +4 -2
  87. data/lib/mihari/analyzers/base.rb +48 -14
  88. data/lib/mihari/analyzers/binaryedge.rb +10 -15
  89. data/lib/mihari/analyzers/censys.rb +12 -15
  90. data/lib/mihari/analyzers/circl.rb +10 -10
  91. data/lib/mihari/analyzers/crtsh.rb +10 -6
  92. data/lib/mihari/analyzers/dnstwister.rb +6 -8
  93. data/lib/mihari/analyzers/feed.rb +21 -10
  94. data/lib/mihari/analyzers/greynoise.rb +10 -20
  95. data/lib/mihari/analyzers/onyphe.rb +9 -14
  96. data/lib/mihari/analyzers/otx.rb +8 -9
  97. data/lib/mihari/analyzers/passivetotal.rb +10 -10
  98. data/lib/mihari/analyzers/pulsedive.rb +21 -31
  99. data/lib/mihari/analyzers/securitytrails.rb +8 -6
  100. data/lib/mihari/analyzers/shodan.rb +8 -13
  101. data/lib/mihari/analyzers/urlscan.rb +15 -20
  102. data/lib/mihari/analyzers/virustotal.rb +16 -26
  103. data/lib/mihari/analyzers/virustotal_intelligence.rb +11 -17
  104. data/lib/mihari/analyzers/zoomeye.rb +12 -17
  105. data/lib/mihari/config.rb +133 -0
  106. data/lib/mihari/constants.rb +3 -0
  107. data/lib/mihari/emitters/slack.rb +13 -3
  108. data/lib/mihari/errors.rb +1 -1
  109. data/lib/mihari/http.rb +2 -3
  110. data/lib/mihari/schemas/analyzer.rb +2 -0
  111. data/lib/mihari/type_checker.rb +6 -6
  112. data/lib/mihari/version.rb +1 -1
  113. data/lib/mihari/web/endpoints/configs.rb +5 -1
  114. data/lib/mihari/web/public/assets/{index-eed1bcd8.css → index-b17c40c6.css} +1 -5
  115. data/lib/mihari/web/public/assets/index-f740e4f9.js +799 -0
  116. data/lib/mihari/web/public/index.html +2 -2
  117. data/lib/mihari/web/public/redoc-static.html +388 -2193
  118. data/lib/mihari.rb +9 -59
  119. data/mihari.gemspec +8 -8
  120. metadata +29 -117
  121. data/frontend/.browserslistrc +0 -3
  122. data/frontend/.eslintrc.js +0 -33
  123. data/frontend/babel.config.js +0 -3
  124. data/frontend/jest.config.js +0 -9
  125. data/frontend/tests/unit/utils.spec.ts +0 -7
  126. data/frontend/vite.config.js +0 -24
  127. data/lib/mihari/web/public/assets/fa-brands-400-20c4a58b.ttf +0 -0
  128. data/lib/mihari/web/public/assets/fa-brands-400-74833209.woff2 +0 -0
  129. data/lib/mihari/web/public/assets/fa-regular-400-528d022d.ttf +0 -0
  130. data/lib/mihari/web/public/assets/fa-regular-400-8e7e5ea1.woff2 +0 -0
  131. data/lib/mihari/web/public/assets/fa-solid-900-67a65763.ttf +0 -0
  132. data/lib/mihari/web/public/assets/fa-solid-900-7152a693.woff2 +0 -0
  133. data/lib/mihari/web/public/assets/fa-v4compatibility-0515a423.ttf +0 -0
  134. data/lib/mihari/web/public/assets/fa-v4compatibility-694a17c3.woff2 +0 -0
  135. data/lib/mihari/web/public/assets/index-ac4e5ffa.js +0 -50
@@ -1,21 +1,29 @@
1
1
  {
2
- "name": "mihari-frontend",
2
+ "name": "mihari",
3
3
  "version": "0.1.0",
4
4
  "private": true,
5
5
  "scripts": {
6
- "serve": "vite",
7
- "build": "npx redoc-cli build src/swagger.yaml -o public/redoc-static.html && vite build",
8
- "test:unit": "jest",
9
- "lint": "eslint --ext .js,.vue,.ts --ignore-path .gitignore --fix src --fix tests"
6
+ "build-only": "vite build",
7
+ "build-redoc": "npx @redocly/cli build-docs src/swagger.yaml -o public/redoc-static.html",
8
+ "build": "run-p type-check build-only build-redoc",
9
+ "dev": "vite",
10
+ "format": "prettier --write src/",
11
+ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
12
+ "preview": "vite preview",
13
+ "test:unit": "vitest",
14
+ "type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false"
10
15
  },
11
16
  "dependencies": {
12
- "@fortawesome/fontawesome-free": "^6.4.0",
13
- "@vueuse/core": "^10.2.0",
14
- "@vueuse/router": "^10.2.0",
17
+ "@fortawesome/fontawesome-svg-core": "^6.4.0",
18
+ "@fortawesome/free-solid-svg-icons": "^6.4.0",
19
+ "@fortawesome/vue-fontawesome": "^3.0.3",
20
+ "@vueuse/core": "^10.2.1",
21
+ "@vueuse/router": "^10.2.1",
15
22
  "axios": "^1.4.0",
16
23
  "bulma": "^0.9.4",
17
24
  "bulma-helpers": "^0.4.3",
18
- "dayjs": "^1.11.8",
25
+ "dayjs": "^1.11.9",
26
+ "font-awesome-animation": "^1.1.1",
19
27
  "js-sha256": "^0.9.0",
20
28
  "truncate": "^3.0.0",
21
29
  "ts-dedent": "^2.2.0",
@@ -25,30 +33,35 @@
25
33
  "vue-concurrency": "4.0.1",
26
34
  "vue-json-pretty": "^2.2.4",
27
35
  "vue-prism-editor": "^2.0.0-alpha.2",
28
- "vue-router": "^4.2.2"
36
+ "vue-router": "^4.2.4"
29
37
  },
30
38
  "devDependencies": {
31
- "@types/jest": "29.5.2",
39
+ "@redocly/cli": "^1.0.0-beta.131",
40
+ "@rushstack/eslint-patch": "^1.3.2",
41
+ "@tsconfig/node20": "^1.0.2",
42
+ "@types/jsdom": "^21.1.1",
43
+ "@types/node": "^20.4.2",
32
44
  "@types/prismjs": "^1.26.0",
33
45
  "@types/url-parse": "^1.4.8",
34
- "@typescript-eslint/eslint-plugin": "^5.59.11",
35
- "@typescript-eslint/parser": "^5.59.11",
46
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
47
+ "@typescript-eslint/parser": "^6.0.0",
36
48
  "@vitejs/plugin-vue": "^4.2.3",
49
+ "@vue/eslint-config-prettier": "^7.1.0",
37
50
  "@vue/eslint-config-typescript": "^11.0.3",
38
- "@vue/test-utils": "2.3.2",
39
- "@vue/vue3-jest": "^29.2.4",
40
- "eslint": "^8.43.0",
51
+ "@vue/test-utils": "2.4.0",
52
+ "@vue/tsconfig": "^0.4.0",
53
+ "eslint": "^8.45.0",
41
54
  "eslint-config-prettier": "^8.8.0",
42
- "eslint-plugin-prettier": "^4.2.1",
55
+ "eslint-plugin-prettier": "^5.0.0",
43
56
  "eslint-plugin-simple-import-sort": "^10.0.0",
44
- "eslint-plugin-vue": "^9.14.1",
45
- "handlebars": "^4.7.7",
57
+ "eslint-plugin-vue": "^9.15.1",
46
58
  "husky": "^8.0.3",
47
- "prettier": "^2.8.8",
48
- "redoc": "2.0.0",
49
- "redoc-cli": "^0.13.21",
50
- "ts-jest": "^29.1.0",
51
- "typescript": "~5.1.3",
52
- "vite": "^4.3.9"
59
+ "jsdom": "^22.1.0",
60
+ "npm-run-all": "^4.1.5",
61
+ "prettier": "^3.0.0",
62
+ "typescript": "~5.1.6",
63
+ "vite": "^4.4.4",
64
+ "vitest": "^0.33.0",
65
+ "vue-tsc": "^1.8.5"
53
66
  }
54
67
  }
data/frontend/src/App.vue CHANGED
@@ -8,16 +8,16 @@
8
8
  </template>
9
9
 
10
10
  <script lang="ts">
11
- import { defineComponent } from "vue";
11
+ import { defineComponent } from "vue"
12
12
 
13
- import Navbar from "@/components/Navbar.vue";
13
+ import Navbar from "@/components/Navbar.vue"
14
14
 
15
15
  export default defineComponent({
16
16
  name: "App",
17
17
  components: {
18
- Navbar,
19
- },
20
- });
18
+ Navbar
19
+ }
20
+ })
21
21
  </script>
22
22
 
23
23
  <style>
@@ -1,7 +1,7 @@
1
- import { Task, useAsyncTask } from "vue-concurrency";
1
+ import { type Task, useAsyncTask } from "vue-concurrency"
2
2
 
3
- import { API } from "@/api";
4
- import {
3
+ import { API } from "@/api"
4
+ import type {
5
5
  Alerts,
6
6
  AlertSearchParams,
7
7
  ArtifactWithTags,
@@ -11,103 +11,101 @@ import {
11
11
  Rule,
12
12
  Rules,
13
13
  RuleSearchParams,
14
- UpdateRule,
15
- } from "@/types";
14
+ UpdateRule
15
+ } from "@/types"
16
16
 
17
17
  export function generateGetAlertsTask(): Task<Alerts, [AlertSearchParams]> {
18
18
  return useAsyncTask<Alerts, [AlertSearchParams]>(async (_signal, params) => {
19
- return await API.getAlerts(params);
20
- });
19
+ return await API.getAlerts(params)
20
+ })
21
21
  }
22
22
 
23
23
  export function generateDeleteAlertTask(): Task<void, [string]> {
24
24
  return useAsyncTask<void, [string]>(async (_signal, id) => {
25
- return await API.deleteAlert(id);
26
- });
25
+ return await API.deleteAlert(id)
26
+ })
27
27
  }
28
28
 
29
29
  export function generateGetTagsTask(): Task<string[], []> {
30
30
  return useAsyncTask<string[], []>(async () => {
31
- return await API.getTags();
32
- });
31
+ return await API.getTags()
32
+ })
33
33
  }
34
34
 
35
35
  export function generateDeleteTagTask(): Task<void, [string]> {
36
36
  return useAsyncTask<void, [string]>(async (_signal, tag) => {
37
- return await API.deleteTag(tag);
38
- });
37
+ return await API.deleteTag(tag)
38
+ })
39
39
  }
40
40
 
41
41
  export function generateGetRuleSetTask(): Task<string[], []> {
42
42
  return useAsyncTask<string[], []>(async () => {
43
- return await API.getRuleSet();
44
- });
43
+ return await API.getRuleSet()
44
+ })
45
45
  }
46
46
 
47
47
  export function generateGetArtifactTask(): Task<ArtifactWithTags, [string]> {
48
48
  return useAsyncTask<ArtifactWithTags, [string]>(async (_signal, id) => {
49
- return await API.getArtifact(id);
50
- });
49
+ return await API.getArtifact(id)
50
+ })
51
51
  }
52
52
 
53
53
  export function generateDeleteArtifactTask(): Task<void, [string]> {
54
54
  return useAsyncTask<void, [string]>(async (_signal, id) => {
55
- return await API.deleteArtifact(id);
56
- });
55
+ return await API.deleteArtifact(id)
56
+ })
57
57
  }
58
58
 
59
59
  export function generateEnrichArtifactTask(): Task<void, [string]> {
60
60
  return useAsyncTask<void, [string]>(async (_signal, id) => {
61
- return await API.enrichArtifact(id);
62
- });
61
+ return await API.enrichArtifact(id)
62
+ })
63
63
  }
64
64
 
65
65
  export function generateGetConfigsTask(): Task<Config[], []> {
66
66
  return useAsyncTask<Config[], []>(async () => {
67
- return await API.getConfigs();
68
- });
67
+ return await API.getConfigs()
68
+ })
69
69
  }
70
70
 
71
71
  export function generateGetIPTask(): Task<IPInfo, [string]> {
72
72
  return useAsyncTask<IPInfo, [string]>(async (_signal, ipAddress: string) => {
73
- return await API.getIPInfo(ipAddress);
74
- });
73
+ return await API.getIPInfo(ipAddress)
74
+ })
75
75
  }
76
76
 
77
77
  export function generateGetRulesTask(): Task<Rules, [RuleSearchParams]> {
78
- return useAsyncTask<Rules, [RuleSearchParams]>(
79
- async (_signal, params: RuleSearchParams) => {
80
- return await API.getRules(params);
81
- }
82
- );
78
+ return useAsyncTask<Rules, [RuleSearchParams]>(async (_signal, params: RuleSearchParams) => {
79
+ return await API.getRules(params)
80
+ })
83
81
  }
84
82
 
85
83
  export function generateGetRuleTask(): Task<Rule, [string]> {
86
84
  return useAsyncTask<Rule, [string]>(async (_signal, id: string) => {
87
- return await API.getRule(id);
88
- });
85
+ return await API.getRule(id)
86
+ })
89
87
  }
90
88
 
91
89
  export function generateDeleteRuleTask(): Task<void, [string]> {
92
90
  return useAsyncTask<void, [string]>(async (_signal, id: string) => {
93
- return await API.deleteRule(id);
94
- });
91
+ return await API.deleteRule(id)
92
+ })
95
93
  }
96
94
 
97
95
  export function generateRunRuleTask(): Task<void, [string]> {
98
96
  return useAsyncTask<void, [string]>(async (_signal, id) => {
99
- return await API.runRule(id);
100
- });
97
+ return await API.runRule(id)
98
+ })
101
99
  }
102
100
 
103
101
  export function generateCreateRuleTask(): Task<Rule, [CreateRule]> {
104
102
  return useAsyncTask<Rule, [CreateRule]>(async (_signal, payload) => {
105
- return await API.createRule(payload);
106
- });
103
+ return await API.createRule(payload)
104
+ })
107
105
  }
108
106
 
109
107
  export function generateUpdateRuleTask(): Task<Rule, [UpdateRule]> {
110
108
  return useAsyncTask<Rule, [UpdateRule]>(async (_signal, payload) => {
111
- return await API.updateRule(payload);
112
- });
109
+ return await API.updateRule(payload)
110
+ })
113
111
  }
data/frontend/src/api.ts CHANGED
@@ -1,6 +1,6 @@
1
- import axios from "axios";
1
+ import axios from "axios"
2
2
 
3
- import {
3
+ import type {
4
4
  Alerts,
5
5
  AlertSearchParams,
6
6
  ArtifactWithTags,
@@ -12,94 +12,94 @@ import {
12
12
  RuleSearchParams,
13
13
  RuleSet,
14
14
  Tags,
15
- UpdateRule,
16
- } from "@/types";
15
+ UpdateRule
16
+ } from "@/types"
17
17
 
18
18
  const client = axios.create({
19
19
  headers: {
20
- Accept: "application/json",
21
- },
22
- });
20
+ Accept: "application/json"
21
+ }
22
+ })
23
23
 
24
24
  export const API = {
25
25
  async getConfigs(): Promise<Config[]> {
26
- const res = await client.get<Config[]>("/api/configs");
27
- return res.data;
26
+ const res = await client.get<Config[]>("/api/configs")
27
+ return res.data
28
28
  },
29
29
 
30
30
  async getAlerts(params: AlertSearchParams): Promise<Alerts> {
31
- params.page = params.page || 1;
31
+ params.page = params.page || 1
32
32
  const res = await client.get<Alerts>("/api/alerts", {
33
- params: params,
34
- });
35
- return res.data;
33
+ params: params
34
+ })
35
+ return res.data
36
36
  },
37
37
 
38
38
  async getTags(): Promise<string[]> {
39
- const res = await client.get<Tags>("/api/tags");
40
- return res.data.tags;
39
+ const res = await client.get<Tags>("/api/tags")
40
+ return res.data.tags
41
41
  },
42
42
 
43
43
  async getRuleSet(): Promise<string[]> {
44
- const res = await client.get<RuleSet>("/api/rules/ids");
45
- return res.data.ruleIds;
44
+ const res = await client.get<RuleSet>("/api/rules/ids")
45
+ return res.data.ruleIds
46
46
  },
47
47
 
48
48
  async deleteAlert(id: string): Promise<void> {
49
- await client.delete(`/api/alerts/${id}`);
49
+ await client.delete(`/api/alerts/${id}`)
50
50
  },
51
51
 
52
52
  async getArtifact(id: string): Promise<ArtifactWithTags> {
53
- const res = await client.get(`/api/artifacts/${id}`);
54
- return res.data;
53
+ const res = await client.get(`/api/artifacts/${id}`)
54
+ return res.data
55
55
  },
56
56
 
57
57
  async enrichArtifact(id: string): Promise<void> {
58
- await client.get(`/api/artifacts/${id}/enrich`);
59
- return;
58
+ await client.get(`/api/artifacts/${id}/enrich`)
59
+ return
60
60
  },
61
61
 
62
62
  async deleteArtifact(id: string): Promise<void> {
63
- await client.delete(`/api/artifacts/${id}`);
63
+ await client.delete(`/api/artifacts/${id}`)
64
64
  },
65
65
 
66
66
  async getRules(params: RuleSearchParams): Promise<Rules> {
67
- params.page = params.page || 1;
67
+ params.page = params.page || 1
68
68
  const res = await client.get<Rules>("/api/rules", {
69
- params: params,
70
- });
71
- return res.data;
69
+ params: params
70
+ })
71
+ return res.data
72
72
  },
73
73
 
74
74
  async getRule(id: string): Promise<Rule> {
75
- const res = await client.get<Rule>(`/api/rules/${id}`);
76
- return res.data;
75
+ const res = await client.get<Rule>(`/api/rules/${id}`)
76
+ return res.data
77
77
  },
78
78
 
79
79
  async runRule(id: string): Promise<void> {
80
- await client.get<void>(`/api/rules/${id}/run`);
80
+ await client.get<void>(`/api/rules/${id}/run`)
81
81
  },
82
82
 
83
83
  async createRule(payload: CreateRule): Promise<Rule> {
84
- const res = await client.post<Rule>("/api/rules/", payload);
85
- return res.data;
84
+ const res = await client.post<Rule>("/api/rules/", payload)
85
+ return res.data
86
86
  },
87
87
 
88
88
  async updateRule(payload: UpdateRule): Promise<Rule> {
89
- const res = await client.put<Rule>("/api/rules/", payload);
90
- return res.data;
89
+ const res = await client.put<Rule>("/api/rules/", payload)
90
+ return res.data
91
91
  },
92
92
 
93
93
  async deleteRule(id: string): Promise<void> {
94
- await client.delete<void>(`/api/rules/${id}`);
94
+ await client.delete<void>(`/api/rules/${id}`)
95
95
  },
96
96
 
97
97
  async deleteTag(name: string): Promise<void> {
98
- await client.delete(`/api/tags/${name}`);
98
+ await client.delete(`/api/tags/${name}`)
99
99
  },
100
100
 
101
101
  async getIPInfo(ipAddress: string): Promise<IPInfo> {
102
- const res = await client.get<IPInfo>(`/api/ip_addresses/${ipAddress}`);
103
- return res.data;
104
- },
105
- };
102
+ const res = await client.get<IPInfo>(`/api/ip_addresses/${ipAddress}`)
103
+ return res.data
104
+ }
105
+ }
@@ -12,21 +12,21 @@
12
12
  </template>
13
13
 
14
14
  <script lang="ts">
15
- import "vue-json-pretty/lib/styles.css";
15
+ import "vue-json-pretty/lib/styles.css"
16
16
 
17
- import { defineComponent } from "vue";
18
- import VueJsonPretty from "vue-json-pretty";
17
+ import { defineComponent } from "vue"
18
+ import VueJsonPretty from "vue-json-pretty"
19
19
 
20
20
  export default defineComponent({
21
21
  name: "ErrorItem",
22
22
  props: {
23
23
  error: {
24
24
  type: Object,
25
- required: true,
26
- },
25
+ required: true
26
+ }
27
27
  },
28
28
  components: {
29
- VueJsonPretty,
30
- },
31
- });
29
+ VueJsonPretty
30
+ }
31
+ })
32
32
  </script>
@@ -1,15 +1,15 @@
1
1
  <template>
2
2
  <div class="has-text-centered">
3
3
  <div class="fa-3x">
4
- <i class="fas fa-spinner fa-spin"></i>
4
+ <font-awesome-icon icon="spinner" spin></font-awesome-icon>
5
5
  </div>
6
6
  </div>
7
7
  </template>
8
8
 
9
9
  <script lang="ts">
10
- import { defineComponent } from "vue";
10
+ import { defineComponent } from "vue"
11
11
 
12
12
  export default defineComponent({
13
- name: "LoadingItem",
14
- });
13
+ name: "LoadingItem"
14
+ })
15
15
  </script>
@@ -1,9 +1,5 @@
1
1
  <template>
2
- <nav
3
- role="navigation"
4
- aria-label="main navigation"
5
- class="navbar is-fixed-top"
6
- >
2
+ <nav role="navigation" aria-label="main navigation" class="navbar is-fixed-top">
7
3
  <div class="navbar-brand">
8
4
  <a class="navbar-item"><h1 class="title">Mihari</h1></a
9
5
  ><a role="button" aria-label="menu" class="navbar-burger burger"
@@ -14,28 +10,15 @@
14
10
  <div class="navbar-menu">
15
11
  <div class="navbar-start"></div>
16
12
  <div class="navbar-end">
17
- <router-link class="navbar-item" :to="{ name: 'Alerts' }"
18
- >Alerts</router-link
19
- >
20
- <router-link class="navbar-item" :to="{ name: 'NewRule' }"
21
- >New rule</router-link
22
- >
23
- <router-link class="navbar-item" :to="{ name: 'Rules' }"
24
- >Rules</router-link
25
- >
26
- <router-link class="navbar-item" :to="{ name: 'Configs' }"
27
- >Configs</router-link
28
- >
13
+ <router-link class="navbar-item" :to="{ name: 'Alerts' }">Alerts</router-link>
14
+ <router-link class="navbar-item" :to="{ name: 'NewRule' }">New rule</router-link>
15
+ <router-link class="navbar-item" :to="{ name: 'Rules' }">Rules</router-link>
16
+ <router-link class="navbar-item" :to="{ name: 'Configs' }">Configs</router-link>
29
17
  <a class="navbar-item"
30
- ><a href="/redoc-static.html" target="_blank" class="navbar-item"
31
- >API</a
32
- ></a
18
+ ><a href="/redoc-static.html" target="_blank" class="navbar-item">API</a></a
33
19
  >
34
20
  <a class="navbar-item"
35
- ><a
36
- href="https://github.com/ninoseki/mihari"
37
- target="_blank"
38
- class="navbar-item"
21
+ ><a href="https://github.com/ninoseki/mihari" target="_blank" class="navbar-item"
39
22
  >GitHub</a
40
23
  ></a
41
24
  >
@@ -45,11 +28,11 @@
45
28
  </template>
46
29
 
47
30
  <script lang="ts">
48
- import { defineComponent } from "vue";
31
+ import { defineComponent } from "vue"
49
32
 
50
33
  export default defineComponent({
51
- name: "NavbarItem",
52
- });
34
+ name: "NavbarItem"
35
+ })
53
36
  </script>
54
37
 
55
38
  <style scoped>
@@ -21,10 +21,7 @@
21
21
  >
22
22
  </li>
23
23
  <li>
24
- <a
25
- class="pagination-link mt-2 is-current"
26
- @click="updatePage(currentPage)"
27
- >
24
+ <a class="pagination-link mt-2 is-current" @click="updatePage(currentPage)">
28
25
  {{ currentPage }}</a
29
26
  >
30
27
  </li>
@@ -37,80 +34,76 @@
37
34
  <span class="pagination-ellipsis">&hellip;</span>
38
35
  </li>
39
36
  <li v-if="hasNextPage && isNextPageNotLast">
40
- <a class="pagination-link mt-2" @click="updatePage(totalPageCount)">{{
41
- totalPageCount
42
- }}</a>
37
+ <a class="pagination-link mt-2" @click="updatePage(totalPageCount)">{{ totalPageCount }}</a>
43
38
  </li>
44
39
  </ul>
45
40
  </nav>
46
41
  </template>
47
42
 
48
43
  <script lang="ts">
49
- import { useRouteQuery } from "@vueuse/router";
50
- import { computed, defineComponent, onMounted, Ref } from "vue";
51
- import { useRoute, useRouter } from "vue-router";
44
+ import { useRouteQuery } from "@vueuse/router"
45
+ import { computed, defineComponent, onMounted, type Ref } from "vue"
46
+ import { useRoute, useRouter } from "vue-router"
52
47
 
53
48
  export default defineComponent({
54
49
  name: "AlertsPagination",
55
50
  props: {
56
51
  currentPage: {
57
52
  type: Number,
58
- required: true,
53
+ required: true
59
54
  },
60
55
  pageSize: {
61
56
  type: Number,
62
- required: true,
57
+ required: true
63
58
  },
64
59
  total: {
65
60
  type: Number,
66
- required: true,
67
- },
61
+ required: true
62
+ }
68
63
  },
69
64
  emits: ["update-page"],
70
65
  setup(props, context) {
71
- const route = useRoute();
72
- const router = useRouter();
73
- const options = { route, router };
66
+ const route = useRoute()
67
+ const router = useRouter()
68
+ const options = { route, router }
74
69
 
75
70
  const totalPageCount = computed(() => {
76
- return Math.ceil(props.total / props.pageSize);
77
- });
71
+ return Math.ceil(props.total / props.pageSize)
72
+ })
78
73
 
79
74
  const hasOnlyOnePage = computed(() => {
80
- return totalPageCount.value === 1;
81
- });
75
+ return totalPageCount.value === 1
76
+ })
82
77
 
83
78
  const hasPreviousPage = computed(() => {
84
- return props.currentPage > 1;
85
- });
79
+ return props.currentPage > 1
80
+ })
86
81
 
87
82
  const isPreviousPageNotFirst = computed(() => {
88
- return props.currentPage - 1 !== 1;
89
- });
83
+ return props.currentPage - 1 !== 1
84
+ })
90
85
 
91
86
  const hasNextPage = computed(() => {
92
- return props.currentPage < totalPageCount.value;
93
- });
87
+ return props.currentPage < totalPageCount.value
88
+ })
94
89
 
95
90
  const isNextPageNotLast = computed(() => {
96
- return props.currentPage + 1 !== totalPageCount.value;
97
- });
91
+ return props.currentPage + 1 !== totalPageCount.value
92
+ })
98
93
 
99
94
  const updatePage = (page: number) => {
100
- const pageQuery = useRouteQuery("page", page.toString(), options);
101
- pageQuery.value = page.toString();
95
+ const pageQuery = useRouteQuery("page", page.toString(), options)
96
+ pageQuery.value = page.toString()
102
97
 
103
- context.emit("update-page", page);
104
- };
98
+ context.emit("update-page", page)
99
+ }
105
100
 
106
101
  onMounted(() => {
107
- const pageQuery = useRouteQuery("page", null, options) as Ref<
108
- string | null
109
- >;
102
+ const pageQuery = useRouteQuery("page", null, options) as Ref<string | null>
110
103
  if (pageQuery.value && parseInt(pageQuery.value) !== props.currentPage) {
111
- updatePage(parseInt(pageQuery.value));
104
+ updatePage(parseInt(pageQuery.value))
112
105
  }
113
- });
106
+ })
114
107
 
115
108
  return {
116
109
  updatePage,
@@ -119,8 +112,8 @@ export default defineComponent({
119
112
  hasPreviousPage,
120
113
  isNextPageNotLast,
121
114
  isPreviousPageNotFirst,
122
- totalPageCount,
123
- };
124
- },
125
- });
115
+ totalPageCount
116
+ }
117
+ }
118
+ })
126
119
  </script>