mihari 5.2.4 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/README.md +0 -10
  4. data/Rakefile +7 -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 +5095 -9661
  11. data/frontend/package.json +34 -24
  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 +3 -3
  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 +21 -26
  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 +42 -49
  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 +66 -83
  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 +7 -10
  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 +22 -22
  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 +18 -18
  44. data/frontend/src/components/rule/Rule.vue +25 -27
  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 +39 -42
  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 +8 -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-2ba8f0a6.css} +1 -1
  115. data/lib/mihari/web/public/assets/{index-ac4e5ffa.js → index-71285b15.js} +16 -16
  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 +24 -62
  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
@@ -3,18 +3,18 @@
3
3
  </template>
4
4
 
5
5
  <script lang="ts">
6
- import { useTitle } from "@vueuse/core";
7
- import { defineComponent } from "vue";
6
+ import { useTitle } from "@vueuse/core"
7
+ import { defineComponent } from "vue"
8
8
 
9
- import Alerts from "@/components/alert/AlertsWrapper.vue";
9
+ import Alerts from "@/components/alert/AlertsWrapper.vue"
10
10
 
11
11
  export default defineComponent({
12
12
  name: "AlertsView",
13
13
  components: {
14
- Alerts,
14
+ Alerts
15
15
  },
16
16
  setup() {
17
- useTitle("Alerts - Mihari");
18
- },
19
- });
17
+ useTitle("Alerts - Mihari")
18
+ }
19
+ })
20
20
  </script>
@@ -3,42 +3,42 @@
3
3
  </template>
4
4
 
5
5
  <script lang="ts">
6
- import { useTitle } from "@vueuse/core";
7
- import { defineComponent, onMounted, ref, watch } from "vue";
6
+ import { useTitle } from "@vueuse/core"
7
+ import { defineComponent, onMounted, ref, watch } from "vue"
8
8
 
9
- import Artifact from "@/components/artifact/ArtifactWrapper.vue";
9
+ import Artifact from "@/components/artifact/ArtifactWrapper.vue"
10
10
 
11
11
  export default defineComponent({
12
12
  name: "ArtifactView",
13
13
  components: {
14
- Artifact,
14
+ Artifact
15
15
  },
16
16
  props: {
17
17
  id: {
18
18
  type: String,
19
- required: true,
20
- },
19
+ required: true
20
+ }
21
21
  },
22
22
  setup(props) {
23
- const artifactId = ref<string>(props.id);
23
+ const artifactId = ref<string>(props.id)
24
24
 
25
25
  const updateTitle = () => {
26
- useTitle(`Artifact:${artifactId.value} - Mihari`);
27
- };
26
+ useTitle(`Artifact:${artifactId.value} - Mihari`)
27
+ }
28
28
 
29
29
  onMounted(() => {
30
- updateTitle();
31
- });
30
+ updateTitle()
31
+ })
32
32
 
33
33
  watch(
34
34
  () => props.id,
35
35
  () => {
36
- artifactId.value = props.id;
37
- updateTitle();
36
+ artifactId.value = props.id
37
+ updateTitle()
38
38
  }
39
- );
39
+ )
40
40
 
41
- return { artifactId };
42
- },
43
- });
41
+ return { artifactId }
42
+ }
43
+ })
44
44
  </script>
@@ -3,18 +3,18 @@
3
3
  </template>
4
4
 
5
5
  <script lang="ts">
6
- import { useTitle } from "@vueuse/core";
7
- import { defineComponent } from "vue";
6
+ import { useTitle } from "@vueuse/core"
7
+ import { defineComponent } from "vue"
8
8
 
9
- import Configs from "@/components/config/ConfigsWrapper.vue";
9
+ import Configs from "@/components/config/ConfigsWrapper.vue"
10
10
 
11
11
  export default defineComponent({
12
12
  name: "ConfigView",
13
13
  components: {
14
- Configs,
14
+ Configs
15
15
  },
16
16
  setup() {
17
- useTitle("Config - Mihari");
18
- },
19
- });
17
+ useTitle("Config - Mihari")
18
+ }
19
+ })
20
20
  </script>
@@ -3,42 +3,42 @@
3
3
  </template>
4
4
 
5
5
  <script lang="ts">
6
- import { useTitle } from "@vueuse/core";
7
- import { defineComponent, onMounted, ref, watch } from "vue";
6
+ import { useTitle } from "@vueuse/core"
7
+ import { defineComponent, onMounted, ref, watch } from "vue"
8
8
 
9
- import EditRule from "@/components/rule/EditRuleWrapper.vue";
9
+ import EditRule from "@/components/rule/EditRuleWrapper.vue"
10
10
 
11
11
  export default defineComponent({
12
12
  name: "EditRuleView",
13
13
  components: {
14
- EditRule,
14
+ EditRule
15
15
  },
16
16
  props: {
17
17
  id: {
18
18
  type: String,
19
- required: true,
20
- },
19
+ required: true
20
+ }
21
21
  },
22
22
  setup(props) {
23
- const ruleId = ref<string>(props.id);
23
+ const ruleId = ref<string>(props.id)
24
24
 
25
25
  const updateTitle = () => {
26
- useTitle(`Edit rule:${ruleId.value} - Mihari`);
27
- };
26
+ useTitle(`Edit rule:${ruleId.value} - Mihari`)
27
+ }
28
28
 
29
29
  onMounted(() => {
30
- updateTitle();
31
- });
30
+ updateTitle()
31
+ })
32
32
 
33
33
  watch(
34
34
  () => props.id,
35
35
  () => {
36
- ruleId.value = props.id;
37
- updateTitle();
36
+ ruleId.value = props.id
37
+ updateTitle()
38
38
  }
39
- );
39
+ )
40
40
 
41
- return { ruleId };
42
- },
43
- });
41
+ return { ruleId }
42
+ }
43
+ })
44
44
  </script>
@@ -3,24 +3,24 @@
3
3
  </template>
4
4
 
5
5
  <script lang="ts">
6
- import { useTitle } from "@vueuse/core";
7
- import { defineComponent, onMounted } from "vue";
6
+ import { useTitle } from "@vueuse/core"
7
+ import { defineComponent, onMounted } from "vue"
8
8
 
9
- import NewRule from "@/components/rule/NewRule.vue";
9
+ import NewRule from "@/components/rule/NewRule.vue"
10
10
 
11
11
  export default defineComponent({
12
12
  name: "NewRuleView",
13
13
  components: {
14
- NewRule,
14
+ NewRule
15
15
  },
16
16
  setup() {
17
17
  const updateTitle = () => {
18
- useTitle(`New rule - Mihari`);
19
- };
18
+ useTitle(`New rule - Mihari`)
19
+ }
20
20
 
21
21
  onMounted(() => {
22
- updateTitle();
23
- });
24
- },
25
- });
22
+ updateTitle()
23
+ })
24
+ }
25
+ })
26
26
  </script>
@@ -3,42 +3,42 @@
3
3
  </template>
4
4
 
5
5
  <script lang="ts">
6
- import { useTitle } from "@vueuse/core";
7
- import { defineComponent, onMounted, ref, watch } from "vue";
6
+ import { useTitle } from "@vueuse/core"
7
+ import { defineComponent, onMounted, ref, watch } from "vue"
8
8
 
9
- import Rule from "@/components/rule/RuleWrapper.vue";
9
+ import Rule from "@/components/rule/RuleWrapper.vue"
10
10
 
11
11
  export default defineComponent({
12
12
  name: "RuleView",
13
13
  components: {
14
- Rule,
14
+ Rule
15
15
  },
16
16
  props: {
17
17
  id: {
18
18
  type: String,
19
- required: true,
20
- },
19
+ required: true
20
+ }
21
21
  },
22
22
  setup(props) {
23
- const ruleId = ref<string>(props.id);
23
+ const ruleId = ref<string>(props.id)
24
24
 
25
25
  const updateTitle = () => {
26
- useTitle(`Rule:${ruleId.value} - Mihari`);
27
- };
26
+ useTitle(`Rule:${ruleId.value} - Mihari`)
27
+ }
28
28
 
29
29
  onMounted(() => {
30
- updateTitle();
31
- });
30
+ updateTitle()
31
+ })
32
32
 
33
33
  watch(
34
34
  () => props.id,
35
35
  () => {
36
- ruleId.value = props.id;
37
- updateTitle();
36
+ ruleId.value = props.id
37
+ updateTitle()
38
38
  }
39
- );
39
+ )
40
40
 
41
- return { ruleId };
42
- },
43
- });
41
+ return { ruleId }
42
+ }
43
+ })
44
44
  </script>
@@ -3,18 +3,18 @@
3
3
  </template>
4
4
 
5
5
  <script lang="ts">
6
- import { useTitle } from "@vueuse/core";
7
- import { defineComponent } from "vue";
6
+ import { useTitle } from "@vueuse/core"
7
+ import { defineComponent } from "vue"
8
8
 
9
- import Rules from "@/components/rule/RulesWrapper.vue";
9
+ import Rules from "@/components/rule/RulesWrapper.vue"
10
10
 
11
11
  export default defineComponent({
12
12
  name: "RulesView",
13
13
  components: {
14
- Rules,
14
+ Rules
15
15
  },
16
16
  setup() {
17
- useTitle("Rules - Mihari");
18
- },
19
- });
17
+ useTitle("Rules - Mihari")
18
+ }
19
+ })
20
20
  </script>
@@ -0,0 +1,9 @@
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
+ })
@@ -0,0 +1,21 @@
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,40 +1,14 @@
1
1
  {
2
- "compilerOptions": {
3
- "target": "esnext",
4
- "module": "esnext",
5
- "strict": true,
6
- "jsx": "preserve",
7
- "importHelpers": true,
8
- "moduleResolution": "node",
9
- "skipLibCheck": true,
10
- "esModuleInterop": true,
11
- "allowSyntheticDefaultImports": true,
12
- "sourceMap": true,
13
- "baseUrl": ".",
14
- "types": [
15
- "webpack-env",
16
- "jest"
17
- ],
18
- "paths": {
19
- "@/*": [
20
- "src/*"
21
- ]
2
+ "files": [],
3
+ "references": [
4
+ {
5
+ "path": "./tsconfig.node.json"
22
6
  },
23
- "lib": [
24
- "esnext",
25
- "dom",
26
- "dom.iterable",
27
- "scripthost"
28
- ]
29
- },
30
- "include": [
31
- "src/**/*.ts",
32
- "src/**/*.tsx",
33
- "src/**/*.vue",
34
- "tests/**/*.ts",
35
- "tests/**/*.tsx"
36
- ],
37
- "exclude": [
38
- "node_modules"
7
+ {
8
+ "path": "./tsconfig.app.json"
9
+ },
10
+ {
11
+ "path": "./tsconfig.vitest.json"
12
+ }
39
13
  ]
40
14
  }
@@ -0,0 +1,13 @@
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
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "./tsconfig.app.json",
3
+ "exclude": [],
4
+ "compilerOptions": {
5
+ "composite": true,
6
+ "lib": [],
7
+ "types": [
8
+ "node",
9
+ "jsdom"
10
+ ]
11
+ }
12
+ }
@@ -0,0 +1,24 @@
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
+ })
@@ -0,0 +1,21 @@
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
+ )
data/lefthook.yml CHANGED
@@ -3,8 +3,10 @@ pre-commit:
3
3
  commands:
4
4
  standard:
5
5
  glob: "*.rb"
6
- run: bundle exec standardrb --fix {staged_files} && git add {staged_files}
6
+ run: bundle exec standardrb --fix {staged_files}
7
+ stage_fixed: true
7
8
  eslint:
8
9
  root: "frontend/"
9
10
  glob: "*.{js,ts,vue}"
10
- run: npx eslint --fix {staged_files} && git add {staged_files}
11
+ run: npx eslint --fix {staged_files}
12
+ stage_fixed: true
@@ -3,11 +3,45 @@
3
3
  module Mihari
4
4
  module Analyzers
5
5
  class Base
6
- extend Dry::Initializer
7
-
8
6
  include Mixins::Configurable
9
7
  include Mixins::Retriable
10
8
 
9
+ # @return [String]
10
+ attr_reader :query
11
+
12
+ # @return [Hash]
13
+ attr_reader :options
14
+
15
+ #
16
+ # @param [String] query
17
+ # @param [Hash, nil] options
18
+ #
19
+ def initialize(query, options: nil)
20
+ @query = query
21
+ @options = options || {}
22
+ end
23
+
24
+ #
25
+ # @return [Integer, nil]
26
+ #
27
+ def interval
28
+ @interval = options[:interval]
29
+ end
30
+
31
+ #
32
+ # @return [Integer]
33
+ #
34
+ def retry_interval
35
+ @retry_interval ||= options[:retry_interval] || DEFAULT_RETRY_INTERVAL
36
+ end
37
+
38
+ #
39
+ # @return [Integer]
40
+ #
41
+ def retry_times
42
+ @retry_times ||= options[:retry_times] || DEFAULT_RETRY_TIMES
43
+ end
44
+
11
45
  # @return [Array<String>, Array<Mihari::Artifact>]
12
46
  def artifacts
13
47
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
@@ -21,17 +55,14 @@ module Mihari
21
55
  # @return [Array<Mihari::Artifact>]
22
56
  #
23
57
  def normalized_artifacts
24
- retry_on_error do
58
+ retry_on_error(times: retry_times, interval: retry_interval) do
25
59
  @normalized_artifacts ||= artifacts.compact.sort.map do |artifact|
26
60
  # No need to set data_type manually
27
61
  # It is set automatically in #initialize
28
62
  artifact = artifact.is_a?(Artifact) ? artifact : Artifact.new(data: artifact)
29
- artifact
30
- end.select(&:valid?).uniq(&:data).map do |artifact|
31
- # set source
32
63
  artifact.source = source
33
64
  artifact
34
- end
65
+ end.select(&:valid?).uniq(&:data)
35
66
  end
36
67
  end
37
68
 
@@ -51,16 +82,19 @@ module Mihari
51
82
  # @return [Mihari::Analyzers::Base]
52
83
  #
53
84
  def from_query(params)
54
- # get options and set default value as an empty hash
55
- options = params[:options] || {}
85
+ copied = params.deep_dup
86
+
87
+ # convert params into arguments for initialization
88
+ query = copied[:query]
56
89
 
57
- # set interval in the top level
58
- interval = options[:interval]
59
- params[:interval] = interval if interval
90
+ # delete analyzer and query
91
+ %i[analyzer query].each do |key|
92
+ copied.delete key
93
+ end
60
94
 
61
- query = params[:query]
95
+ copied[:options] = copied[:options] || nil
62
96
 
63
- new(query, **params)
97
+ new(query, **copied)
64
98
  end
65
99
 
66
100
  def inherited(child)
@@ -3,23 +3,18 @@
3
3
  module Mihari
4
4
  module Analyzers
5
5
  class BinaryEdge < Base
6
- param :query
7
-
8
- option :interval, default: proc { 0 }
9
-
10
6
  # @return [String, nil]
11
7
  attr_reader :api_key
12
8
 
13
- # @return [String]
14
- attr_reader :query
15
-
16
- # @return [Integer]
17
- attr_reader :interval
18
-
19
- def initialize(*args, **kwargs)
20
- super(*args, **kwargs)
9
+ #
10
+ # @param [String] query
11
+ # @param [Hash, nil] options
12
+ # @param [String, nil] api_key
13
+ #
14
+ def initialize(query, options: nil, api_key: nil)
15
+ super(query, options: options)
21
16
 
22
- @api_key = kwargs[:api_key] || Mihari.config.binaryedge_api_key
17
+ @api_key = api_key || Mihari.config.binaryedge_api_key
23
18
  end
24
19
 
25
20
  def artifacts
@@ -48,7 +43,7 @@ module Mihari
48
43
  #
49
44
  def search_with_page(page: 1)
50
45
  client.search(query, page: page)
51
- rescue UnsuccessfulStatusCodeError => e
46
+ rescue StatusCodeError => e
52
47
  raise RetryableError, e if e.message.include?("Request time limit exceeded")
53
48
 
54
49
  raise e
@@ -69,7 +64,7 @@ module Mihari
69
64
  break if total <= page * PAGE_SIZE
70
65
 
71
66
  # sleep #{interval} seconds to avoid the rate limitation (if it is set)
72
- sleep interval
67
+ sleep(interval) if interval
73
68
  end
74
69
  responses
75
70
  end
@@ -3,27 +3,24 @@
3
3
  module Mihari
4
4
  module Analyzers
5
5
  class Censys < Base
6
- param :query
7
-
8
- option :interval, default: proc { 0 }
9
-
10
6
  # @return [String, nil]
11
7
  attr_reader :id
12
8
 
13
9
  # @return [String, nil]
14
10
  attr_reader :secret
15
11
 
16
- # @return [Integer]
17
- attr_reader :interval
18
-
19
- # @return [String]
20
- attr_reader :query
21
-
22
- def initialize(*args, **kwargs)
23
- super(*args, **kwargs)
12
+ #
13
+ # @param [String] query
14
+ # @param [hash, nil] options
15
+ # @param [String, nil] api_key
16
+ # @param [String, nil] id
17
+ # @param [String, nil] secret
18
+ #
19
+ def initialize(query, options: nil, id: nil, secret: nil)
20
+ super(query, options: options)
24
21
 
25
- @id = kwargs[:id] || Mihari.config.censys_id
26
- @secret = kwargs[:secret] || Mihari.config.censys_secret
22
+ @id = id || Mihari.config.censys_id
23
+ @secret = secret || Mihari.config.censys_secret
27
24
  end
28
25
 
29
26
  #
@@ -45,7 +42,7 @@ module Mihari
45
42
  break if cursor.nil? || cursor.empty?
46
43
 
47
44
  # sleep #{interval} seconds to avoid the rate limitation (if it is set)
48
- sleep interval
45
+ sleep(interval) if interval
49
46
  end
50
47
 
51
48
  artifacts.flatten.uniq(&:data)