mihari 5.7.0 → 5.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/lib/mihari/actor.rb +10 -4
  4. data/lib/mihari/cli/main.rb +2 -0
  5. data/lib/mihari/clients/base.rb +23 -1
  6. data/lib/mihari/clients/binaryedge.rb +1 -3
  7. data/lib/mihari/clients/censys.rb +1 -2
  8. data/lib/mihari/clients/crtsh.rb +2 -3
  9. data/lib/mihari/clients/dnstwister.rb +1 -2
  10. data/lib/mihari/clients/fofa.rb +1 -3
  11. data/lib/mihari/clients/greynoise.rb +1 -2
  12. data/lib/mihari/clients/hunterhow.rb +1 -2
  13. data/lib/mihari/clients/misp.rb +1 -2
  14. data/lib/mihari/clients/onyphe.rb +1 -2
  15. data/lib/mihari/clients/otx.rb +2 -14
  16. data/lib/mihari/clients/passivetotal.rb +3 -16
  17. data/lib/mihari/clients/publsedive.rb +2 -17
  18. data/lib/mihari/clients/securitytrails.rb +3 -25
  19. data/lib/mihari/clients/shodan.rb +1 -2
  20. data/lib/mihari/clients/the_hive.rb +1 -2
  21. data/lib/mihari/clients/urlscan.rb +1 -2
  22. data/lib/mihari/clients/virustotal.rb +3 -17
  23. data/lib/mihari/clients/zoomeye.rb +9 -19
  24. data/lib/mihari/commands/alert.rb +11 -9
  25. data/lib/mihari/commands/database.rb +4 -1
  26. data/lib/mihari/commands/mixins.rb +11 -0
  27. data/lib/mihari/commands/search.rb +13 -32
  28. data/lib/mihari/constants.rb +1 -1
  29. data/lib/mihari/database.rb +1 -1
  30. data/lib/mihari/enrichers/ipinfo.rb +1 -1
  31. data/lib/mihari/entities/tag.rb +1 -0
  32. data/lib/mihari/http.rb +13 -11
  33. data/lib/mihari/rule.rb +14 -0
  34. data/lib/mihari/service.rb +12 -2
  35. data/lib/mihari/services/alert_builder.rb +81 -8
  36. data/lib/mihari/services/alert_runner.rb +3 -10
  37. data/lib/mihari/services/rule_builder.rb +8 -10
  38. data/lib/mihari/services/rule_runner.rb +2 -25
  39. data/lib/mihari/structs/binaryedge.rb +9 -0
  40. data/lib/mihari/structs/censys.rb +0 -14
  41. data/lib/mihari/structs/fofa.rb +3 -0
  42. data/lib/mihari/structs/google_public_dns.rb +0 -4
  43. data/lib/mihari/structs/greynoise.rb +0 -6
  44. data/lib/mihari/structs/hunterhow.rb +0 -6
  45. data/lib/mihari/structs/ipinfo.rb +0 -2
  46. data/lib/mihari/structs/onyphe.rb +0 -4
  47. data/lib/mihari/structs/shodan.rb +0 -2
  48. data/lib/mihari/structs/urlscan.rb +0 -6
  49. data/lib/mihari/structs/virustotal_intelligence.rb +0 -8
  50. data/lib/mihari/version.rb +1 -1
  51. data/lib/mihari/web/app.rb +20 -17
  52. data/lib/mihari/web/endpoints/alerts.rb +75 -38
  53. data/lib/mihari/web/endpoints/artifacts.rb +60 -53
  54. data/lib/mihari/web/endpoints/ip_addresses.rb +19 -4
  55. data/lib/mihari/web/endpoints/rules.rb +132 -88
  56. data/lib/mihari/web/endpoints/tags.rb +15 -13
  57. data/lib/mihari/web/middleware/error_notification_adapter.rb +8 -3
  58. data/lib/mihari/web/public/assets/{index-821134e2.js → index-ec641cb0.js} +45 -44
  59. data/lib/mihari/web/public/index.html +1 -1
  60. data/lib/mihari/web/public/redoc-static.html +400 -400
  61. data/lib/mihari.rb +0 -2
  62. data/mihari.gemspec +5 -5
  63. data/mkdocs.yml +14 -7
  64. metadata +13 -140
  65. data/docs/alternatives.md +0 -5
  66. data/docs/analyzers/binaryedge.md +0 -26
  67. data/docs/analyzers/censys.md +0 -31
  68. data/docs/analyzers/circl.md +0 -37
  69. data/docs/analyzers/crtsh.md +0 -26
  70. data/docs/analyzers/dnstwister.md +0 -25
  71. data/docs/analyzers/feed.md +0 -73
  72. data/docs/analyzers/fofa.md +0 -31
  73. data/docs/analyzers/greynoise.md +0 -26
  74. data/docs/analyzers/hunterhow.md +0 -33
  75. data/docs/analyzers/index.md +0 -104
  76. data/docs/analyzers/onyphe.md +0 -26
  77. data/docs/analyzers/otx.md +0 -28
  78. data/docs/analyzers/passivetotal.md +0 -52
  79. data/docs/analyzers/pulsedive.md +0 -28
  80. data/docs/analyzers/securitytrails.md +0 -41
  81. data/docs/analyzers/shodan.md +0 -26
  82. data/docs/analyzers/urlscan.md +0 -28
  83. data/docs/analyzers/virustotal.md +0 -43
  84. data/docs/analyzers/virustotal_intelligence.md +0 -33
  85. data/docs/analyzers/zoomeye.md +0 -38
  86. data/docs/configuration.md +0 -35
  87. data/docs/emitters/database.md +0 -22
  88. data/docs/emitters/hive.md +0 -26
  89. data/docs/emitters/index.md +0 -36
  90. data/docs/emitters/misp.md +0 -21
  91. data/docs/emitters/slack.md +0 -21
  92. data/docs/emitters/webhook.md +0 -63
  93. data/docs/enrichers/google_public_dns.md +0 -19
  94. data/docs/enrichers/index.md +0 -35
  95. data/docs/enrichers/ipinfo.md +0 -26
  96. data/docs/enrichers/shodan.md +0 -22
  97. data/docs/enrichers/whois.md +0 -17
  98. data/docs/github_actions.md +0 -43
  99. data/docs/index.md +0 -11
  100. data/docs/installation.md +0 -31
  101. data/docs/requirements.md +0 -13
  102. data/docs/rule.md +0 -168
  103. data/docs/tags.md +0 -3
  104. data/docs/usage.md +0 -103
  105. data/frontend/.eslintrc.cjs +0 -22
  106. data/frontend/.gitignore +0 -31
  107. data/frontend/.prettierrc.json +0 -8
  108. data/frontend/README.md +0 -3
  109. data/frontend/env.d.ts +0 -5
  110. data/frontend/index.html +0 -21
  111. data/frontend/package-lock.json +0 -7219
  112. data/frontend/package.json +0 -67
  113. data/frontend/public/favicon.ico +0 -0
  114. data/frontend/scripts/swagger_doc_to_yaml.rb +0 -23
  115. data/frontend/src/App.vue +0 -27
  116. data/frontend/src/ace-config.ts +0 -6
  117. data/frontend/src/api-helper.ts +0 -111
  118. data/frontend/src/api.ts +0 -105
  119. data/frontend/src/components/ErrorMessage.vue +0 -31
  120. data/frontend/src/components/Loading.vue +0 -15
  121. data/frontend/src/components/Navbar.vue +0 -42
  122. data/frontend/src/components/Pagination.vue +0 -119
  123. data/frontend/src/components/alert/Alert.vue +0 -87
  124. data/frontend/src/components/alert/Alerts.vue +0 -63
  125. data/frontend/src/components/alert/AlertsWithPagination.vue +0 -90
  126. data/frontend/src/components/alert/AlertsWrapper.vue +0 -128
  127. data/frontend/src/components/alert/Form.vue +0 -169
  128. data/frontend/src/components/artifact/AS.vue +0 -23
  129. data/frontend/src/components/artifact/Artifact.vue +0 -287
  130. data/frontend/src/components/artifact/ArtifactTag.vue +0 -64
  131. data/frontend/src/components/artifact/ArtifactTags.vue +0 -29
  132. data/frontend/src/components/artifact/ArtifactWrapper.vue +0 -57
  133. data/frontend/src/components/artifact/CPEs.vue +0 -23
  134. data/frontend/src/components/artifact/DnsRecords.vue +0 -32
  135. data/frontend/src/components/artifact/Ports.vue +0 -23
  136. data/frontend/src/components/artifact/ReverseDnsNames.vue +0 -23
  137. data/frontend/src/components/artifact/Tags.vue +0 -29
  138. data/frontend/src/components/artifact/WhoisRecord.vue +0 -44
  139. data/frontend/src/components/config/Configs.vue +0 -65
  140. data/frontend/src/components/config/ConfigsWrapper.vue +0 -32
  141. data/frontend/src/components/link/Link.vue +0 -32
  142. data/frontend/src/components/link/Links.vue +0 -42
  143. data/frontend/src/components/rule/EditRule.vue +0 -72
  144. data/frontend/src/components/rule/EditRuleWrapper.vue +0 -48
  145. data/frontend/src/components/rule/Form.vue +0 -158
  146. data/frontend/src/components/rule/InputForm.vue +0 -45
  147. data/frontend/src/components/rule/NewRule.vue +0 -57
  148. data/frontend/src/components/rule/Rule.vue +0 -100
  149. data/frontend/src/components/rule/RuleWrapper.vue +0 -53
  150. data/frontend/src/components/rule/Rules.vue +0 -84
  151. data/frontend/src/components/rule/RulesWrapper.vue +0 -121
  152. data/frontend/src/components/rule/YAML.vue +0 -37
  153. data/frontend/src/components/tag/Tag.vue +0 -65
  154. data/frontend/src/components/tag/Tags.vue +0 -37
  155. data/frontend/src/countries.ts +0 -350
  156. data/frontend/src/index.ts +0 -20
  157. data/frontend/src/links/anyrun.ts +0 -19
  158. data/frontend/src/links/base.ts +0 -14
  159. data/frontend/src/links/censys.ts +0 -20
  160. data/frontend/src/links/crtsh.ts +0 -20
  161. data/frontend/src/links/dnslytics.ts +0 -38
  162. data/frontend/src/links/greynoise.ts +0 -20
  163. data/frontend/src/links/index.ts +0 -40
  164. data/frontend/src/links/intezer.ts +0 -20
  165. data/frontend/src/links/otx.ts +0 -33
  166. data/frontend/src/links/securitytrails.ts +0 -38
  167. data/frontend/src/links/shodan.ts +0 -20
  168. data/frontend/src/links/urlscan.ts +0 -50
  169. data/frontend/src/links/virustotal.ts +0 -72
  170. data/frontend/src/main.ts +0 -41
  171. data/frontend/src/router/index.ts +0 -57
  172. data/frontend/src/rule.ts +0 -14
  173. data/frontend/src/shims-vue.d.ts +0 -6
  174. data/frontend/src/swagger.yaml +0 -771
  175. data/frontend/src/types.ts +0 -188
  176. data/frontend/src/utils.ts +0 -54
  177. data/frontend/src/views/Alerts.vue +0 -20
  178. data/frontend/src/views/Artifact.vue +0 -39
  179. data/frontend/src/views/Configs.vue +0 -20
  180. data/frontend/src/views/EditRule.vue +0 -39
  181. data/frontend/src/views/NewRule.vue +0 -26
  182. data/frontend/src/views/Rule.vue +0 -39
  183. data/frontend/src/views/Rules.vue +0 -20
  184. data/frontend/tests/utils.spec.ts +0 -9
  185. data/frontend/tsconfig.app.json +0 -21
  186. data/frontend/tsconfig.json +0 -14
  187. data/frontend/tsconfig.node.json +0 -13
  188. data/frontend/tsconfig.vitest.json +0 -12
  189. data/frontend/vite.config.ts +0 -24
  190. data/frontend/vitest.config.ts +0 -21
  191. data/lib/mihari/mixins/error_notification.rb +0 -21
  192. data/lib/mihari/services/alert_proxy.rb +0 -97
@@ -1,188 +0,0 @@
1
- export interface Pagination {
2
- total: number
3
- currentPage: number
4
- pageSize: number
5
- }
6
-
7
- export interface ConfigValue {
8
- key: string
9
- value: string | null
10
- }
11
-
12
- export interface Config {
13
- name: string
14
- isConfigured: boolean
15
- values: ConfigValue[]
16
- type: string
17
- }
18
-
19
- export interface Tag {
20
- name: string
21
- }
22
-
23
- export interface Tags {
24
- tags: string[]
25
- }
26
-
27
- export interface RuleSet {
28
- ruleIds: string[]
29
- }
30
-
31
- export interface DnsRecord {
32
- resource: string
33
- value: string
34
- }
35
-
36
- export interface Contact {
37
- name: string | null
38
- organization: string | null
39
- }
40
-
41
- export interface Registrar {
42
- name: string | null
43
- organization: string | null
44
- }
45
-
46
- export interface WhoisRecord {
47
- createdOn: Date | null
48
- updatedOn: Date | null
49
- expiresOn: Date | null
50
- registrar: Registrar | null
51
- contacts: Contact[]
52
- }
53
-
54
- export interface AutonomousSystem {
55
- asn: number
56
- }
57
-
58
- export interface Geolocation {
59
- country: string
60
- countryCode: string
61
- }
62
-
63
- export interface ReverseDnsName {
64
- name: string
65
- }
66
-
67
- export interface CPE {
68
- cpe: string
69
- }
70
-
71
- export interface Port {
72
- port: string
73
- }
74
-
75
- export interface Artifact {
76
- id: string
77
- data: string
78
- dataType: string
79
- source: string
80
- metadata: unknown | null
81
- createdAt: string
82
-
83
- autonomousSystem: AutonomousSystem | null
84
- whoisRecord: WhoisRecord | null
85
- geolocation: Geolocation | null
86
-
87
- dnsRecords: DnsRecord[] | null
88
- reverseDnsNames: ReverseDnsName[] | null
89
- cpes: CPE[] | null
90
- ports: Port[] | null
91
- }
92
-
93
- export interface ArtifactWithTags extends Artifact {
94
- tags: string[]
95
- }
96
-
97
- export interface Alert {
98
- id: string
99
- ruleId: string
100
- createdAt: string
101
-
102
- tags: Tag[]
103
- artifacts: Artifact[]
104
- }
105
-
106
- export interface Alerts extends Pagination {
107
- alerts: Alert[]
108
- }
109
-
110
- export interface PaginationParams {
111
- page: number | undefined
112
- }
113
-
114
- export interface AlertSearchParams extends PaginationParams {
115
- artifact: string | undefined
116
- ruleId: string | undefined
117
- tag: string | undefined
118
- fromAt: string | undefined
119
- toAt: string | undefined
120
- }
121
-
122
- export interface IPInfo {
123
- ip: string
124
- hostname: string | null
125
- loc: string
126
- countryCode: string
127
- asn: string
128
- }
129
-
130
- export interface GCS {
131
- lat: number
132
- long: number
133
- }
134
-
135
- export interface Country {
136
- name: string
137
- code: string
138
- lat: number
139
- long: number
140
- }
141
-
142
- export type LinkType = "ip" | "domain" | "url" | "hash"
143
-
144
- export interface Link {
145
- name: string
146
- type: string
147
- baseURL: string
148
- // eslint-disable-next-line no-unused-vars
149
- href(data: string): string
150
- favicon(): string
151
- }
152
-
153
- export interface Rule {
154
- id: string
155
- title: string
156
- description: string
157
- yaml: string
158
- createdAt: string
159
- updatedAt: string
160
- tags: Tag[]
161
- }
162
-
163
- export interface CreateRule {
164
- yaml: string
165
- }
166
-
167
- export interface UpdateRule {
168
- id: string
169
- yaml: string
170
- }
171
-
172
- export interface Query {
173
- analyzer: string
174
- query: string
175
- interval: null
176
- }
177
-
178
- export interface Rules extends Pagination {
179
- rules: Rule[]
180
- }
181
-
182
- export interface RuleSearchParams extends PaginationParams {
183
- description: string | undefined
184
- tag: string | undefined
185
- title: string | undefined
186
- fromAt: string | undefined
187
- toAt: string | undefined
188
- }
@@ -1,54 +0,0 @@
1
- import dayjs from "dayjs"
2
- import relativeTime from "dayjs/plugin/relativeTime"
3
- import timezone from "dayjs/plugin/timezone"
4
- import utc from "dayjs/plugin/utc"
5
- import type { LocationQueryValue } from "vue-router"
6
-
7
- import { getCountryByCode } from "@/countries"
8
- import type { GCS, IPInfo } from "@/types"
9
-
10
- dayjs.extend(relativeTime)
11
- dayjs.extend(timezone)
12
- dayjs.extend(utc)
13
-
14
- export function getLocalDatetime(datetime: string): string {
15
- return dayjs(datetime).local().format("YYYY-MM-DD HH:mm:ss")
16
- }
17
-
18
- export function getHumanizedRelativeTime(datetime: string): string {
19
- return dayjs(datetime).local().fromNow()
20
- }
21
-
22
- export function getGCSByCountryCode(countryCode: string): GCS | undefined {
23
- const country = getCountryByCode(countryCode)
24
- if (country !== undefined) {
25
- return { lat: country.lat, long: country.long }
26
- }
27
- }
28
-
29
- export function getGCSByIPInfo(ipinfo: IPInfo): GCS | undefined {
30
- if (ipinfo.loc !== undefined) {
31
- const numbers = ipinfo.loc.split(",")
32
- if (numbers.length === 2) {
33
- const lat = numbers[0]
34
- const long = numbers[1]
35
-
36
- return { lat: parseFloat(lat), long: parseFloat(long) }
37
- }
38
- }
39
- return getGCSByCountryCode(ipinfo.countryCode)
40
- }
41
-
42
- export function normalizeQueryParam(
43
- param: undefined | null | string | string[] | LocationQueryValue | LocationQueryValue[]
44
- ): string | undefined {
45
- if (param === undefined || param === null) {
46
- return undefined
47
- }
48
-
49
- if (typeof param === "string") {
50
- return param
51
- }
52
-
53
- return param.toString()
54
- }
@@ -1,20 +0,0 @@
1
- <template>
2
- <Alerts></Alerts>
3
- </template>
4
-
5
- <script lang="ts">
6
- import { useTitle } from "@vueuse/core"
7
- import { defineComponent } from "vue"
8
-
9
- import Alerts from "@/components/alert/AlertsWrapper.vue"
10
-
11
- export default defineComponent({
12
- name: "AlertsView",
13
- components: {
14
- Alerts
15
- },
16
- setup() {
17
- useTitle("Alerts - Mihari")
18
- }
19
- })
20
- </script>
@@ -1,39 +0,0 @@
1
- <template>
2
- <Artifact :id="id"></Artifact>
3
- </template>
4
-
5
- <script lang="ts">
6
- import { useTitle } from "@vueuse/core"
7
- import { defineComponent, onMounted, watch } from "vue"
8
-
9
- import Artifact from "@/components/artifact/ArtifactWrapper.vue"
10
-
11
- export default defineComponent({
12
- name: "ArtifactView",
13
- components: {
14
- Artifact
15
- },
16
- props: {
17
- id: {
18
- type: String,
19
- required: true
20
- }
21
- },
22
- setup(props) {
23
- const updateTitle = () => {
24
- useTitle(`Artifact:${props.id} - Mihari`)
25
- }
26
-
27
- onMounted(() => {
28
- updateTitle()
29
- })
30
-
31
- watch(
32
- () => props.id,
33
- () => {
34
- updateTitle()
35
- }
36
- )
37
- }
38
- })
39
- </script>
@@ -1,20 +0,0 @@
1
- <template>
2
- <Configs></Configs>
3
- </template>
4
-
5
- <script lang="ts">
6
- import { useTitle } from "@vueuse/core"
7
- import { defineComponent } from "vue"
8
-
9
- import Configs from "@/components/config/ConfigsWrapper.vue"
10
-
11
- export default defineComponent({
12
- name: "ConfigView",
13
- components: {
14
- Configs
15
- },
16
- setup() {
17
- useTitle("Config - Mihari")
18
- }
19
- })
20
- </script>
@@ -1,39 +0,0 @@
1
- <template>
2
- <EditRule :id="id"></EditRule>
3
- </template>
4
-
5
- <script lang="ts">
6
- import { useTitle } from "@vueuse/core"
7
- import { defineComponent, onMounted, watch } from "vue"
8
-
9
- import EditRule from "@/components/rule/EditRuleWrapper.vue"
10
-
11
- export default defineComponent({
12
- name: "EditRuleView",
13
- components: {
14
- EditRule
15
- },
16
- props: {
17
- id: {
18
- type: String,
19
- required: true
20
- }
21
- },
22
- setup(props) {
23
- const updateTitle = () => {
24
- useTitle(`Edit rule:${props.id} - Mihari`)
25
- }
26
-
27
- onMounted(() => {
28
- updateTitle()
29
- })
30
-
31
- watch(
32
- () => props.id,
33
- () => {
34
- updateTitle()
35
- }
36
- )
37
- }
38
- })
39
- </script>
@@ -1,26 +0,0 @@
1
- <template>
2
- <NewRule></NewRule>
3
- </template>
4
-
5
- <script lang="ts">
6
- import { useTitle } from "@vueuse/core"
7
- import { defineComponent, onMounted } from "vue"
8
-
9
- import NewRule from "@/components/rule/NewRule.vue"
10
-
11
- export default defineComponent({
12
- name: "NewRuleView",
13
- components: {
14
- NewRule
15
- },
16
- setup() {
17
- const updateTitle = () => {
18
- useTitle(`New rule - Mihari`)
19
- }
20
-
21
- onMounted(() => {
22
- updateTitle()
23
- })
24
- }
25
- })
26
- </script>
@@ -1,39 +0,0 @@
1
- <template>
2
- <Rule :id="id"></Rule>
3
- </template>
4
-
5
- <script lang="ts">
6
- import { useTitle } from "@vueuse/core"
7
- import { defineComponent, onMounted, watch } from "vue"
8
-
9
- import Rule from "@/components/rule/RuleWrapper.vue"
10
-
11
- export default defineComponent({
12
- name: "RuleView",
13
- components: {
14
- Rule
15
- },
16
- props: {
17
- id: {
18
- type: String,
19
- required: true
20
- }
21
- },
22
- setup(props) {
23
- const updateTitle = () => {
24
- useTitle(`Rule:${props.id} - Mihari`)
25
- }
26
-
27
- onMounted(() => {
28
- updateTitle()
29
- })
30
-
31
- watch(
32
- () => props.id,
33
- () => {
34
- updateTitle()
35
- }
36
- )
37
- }
38
- })
39
- </script>
@@ -1,20 +0,0 @@
1
- <template>
2
- <Rules></Rules>
3
- </template>
4
-
5
- <script lang="ts">
6
- import { useTitle } from "@vueuse/core"
7
- import { defineComponent } from "vue"
8
-
9
- import Rules from "@/components/rule/RulesWrapper.vue"
10
-
11
- export default defineComponent({
12
- name: "RulesView",
13
- components: {
14
- Rules
15
- },
16
- setup() {
17
- useTitle("Rules - Mihari")
18
- }
19
- })
20
- </script>
@@ -1,9 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
-
3
- import { getHumanizedRelativeTime } from '@/utils'
4
-
5
- describe('getHumanizedRelativeTime', () => {
6
- it('returns a relative time in humanized format', () => {
7
- expect(getHumanizedRelativeTime('1970-01-01 00:00:00')).toContain('years')
8
- })
9
- })
@@ -1,21 +0,0 @@
1
- {
2
- "extends": "@vue/tsconfig/tsconfig.dom.json",
3
- "include": [
4
- "env.d.ts",
5
- "src/**/*",
6
- "src/**/*.vue",
7
- "tests/**/*"
8
- ],
9
- "exclude": [
10
- "src/**/__tests__/*"
11
- ],
12
- "compilerOptions": {
13
- "composite": true,
14
- "baseUrl": ".",
15
- "paths": {
16
- "@/*": [
17
- "./src/*"
18
- ]
19
- }
20
- }
21
- }
@@ -1,14 +0,0 @@
1
- {
2
- "files": [],
3
- "references": [
4
- {
5
- "path": "./tsconfig.node.json"
6
- },
7
- {
8
- "path": "./tsconfig.app.json"
9
- },
10
- {
11
- "path": "./tsconfig.vitest.json"
12
- }
13
- ]
14
- }
@@ -1,13 +0,0 @@
1
- {
2
- "extends": "@tsconfig/node20/tsconfig.json",
3
- "include": [
4
- "vite.config.*",
5
- ],
6
- "compilerOptions": {
7
- "composite": true,
8
- "module": "ESNext",
9
- "types": [
10
- "node"
11
- ]
12
- }
13
- }
@@ -1,12 +0,0 @@
1
- {
2
- "extends": "./tsconfig.app.json",
3
- "exclude": [],
4
- "compilerOptions": {
5
- "composite": true,
6
- "lib": [],
7
- "types": [
8
- "node",
9
- "jsdom"
10
- ]
11
- }
12
- }
@@ -1,24 +0,0 @@
1
- import { fileURLToPath, URL } from "node:url"
2
-
3
- import vue from "@vitejs/plugin-vue"
4
- import { defineConfig } from "vite"
5
-
6
- const env = process.env
7
- const target = env.BACKEND_URL || "http://localhost:9292/"
8
- const port = parseInt(env.port || "8080")
9
-
10
- // https://vitejs.dev/config/
11
- export default defineConfig({
12
- plugins: [vue()],
13
- server: {
14
- port,
15
- proxy: {
16
- "/api": target
17
- }
18
- },
19
- resolve: {
20
- alias: {
21
- "@": fileURLToPath(new URL("./src", import.meta.url))
22
- }
23
- }
24
- })
@@ -1,21 +0,0 @@
1
- import { fileURLToPath } from "node:url"
2
-
3
- import { mergeConfig } from "vite"
4
- import { configDefaults, defineConfig } from "vitest/config"
5
-
6
- import viteConfig from "./vite.config"
7
-
8
- export default mergeConfig(
9
- viteConfig,
10
- defineConfig({
11
- test: {
12
- environment: "jsdom",
13
- exclude: [...configDefaults.exclude, "e2e/*"],
14
- root: fileURLToPath(new URL("./", import.meta.url)),
15
- transformMode: {
16
- web: [/\.[jt]sx$/]
17
- },
18
- include: ["**/__tests__/**/*.?(c|m)[jt]s?(x)", "**/?(*.){test,spec}.?(c|m)[jt]s?(x)"]
19
- }
20
- })
21
- )
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Mixins
5
- #
6
- # Error notification mixin
7
- #
8
- module ErrorNotification
9
- #
10
- # Send an exception notification if there is any error in a block
11
- #
12
- def with_error_notification
13
- yield
14
- rescue StandardError => e
15
- Mihari.logger.error e
16
-
17
- Sentry.capture_exception(e) if Sentry.initialized?
18
- end
19
- end
20
- end
21
- end
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
-
5
- module Mihari
6
- module Services
7
- #
8
- # Alert proxy
9
- #
10
- class AlertProxy < Service
11
- # @return [Hash]
12
- attr_reader :data
13
-
14
- # @return [Array, nil]
15
- attr_reader :errors
16
-
17
- #
18
- # Initialize
19
- #
20
- # @param [Hash] data
21
- #
22
- def initialize(**data)
23
- super()
24
-
25
- @data = data.deep_symbolize_keys
26
- @errors = nil
27
-
28
- validate!
29
- end
30
-
31
- #
32
- # @return [Boolean]
33
- #
34
- def errors?
35
- return false if @errors.nil?
36
-
37
- !@errors.empty?
38
- end
39
-
40
- def validate!
41
- contract = Schemas::AlertContract.new
42
- result = contract.call(data)
43
-
44
- @data = result.to_h
45
- @errors = result.errors
46
-
47
- raise ValidationError.new("Validation failed", errors) if errors?
48
- end
49
-
50
- def [](key)
51
- data key.to_sym
52
- end
53
-
54
- #
55
- # @return [String]
56
- #
57
- def rule_id
58
- @rule_id ||= data[:rule_id]
59
- end
60
-
61
- #
62
- # @return [Array<Mihari::Models::Artifact>]
63
- #
64
- def artifacts
65
- @artifacts ||= data[:artifacts].map do |data|
66
- artifact = Models::Artifact.new(data: data)
67
- artifact.rule_id = rule_id
68
- artifact
69
- end.uniq(&:data).select(&:valid?)
70
- end
71
-
72
- #
73
- # @return [Mihari::Rule]
74
- #
75
- def rule
76
- @rule ||= [].tap do |out|
77
- data = Mihari::Models::Rule.find(rule_id).data
78
- out << Rule.new(**data)
79
- end.first
80
- end
81
-
82
- class << self
83
- #
84
- # Load rule from YAML string
85
- #
86
- # @param [String] yaml
87
- #
88
- # @return [Mihari::Services::Alert]
89
- #
90
- def from_yaml(yaml)
91
- data = YAML.safe_load(yaml, permitted_classes: [Date, Symbol])
92
- new(**data)
93
- end
94
- end
95
- end
96
- end
97
- end