Browse Source

chore(more): and more changes.

jackyalcine 1 year ago
parent
commit
cfef27447e
Signed by: Jacky Alciné <yo@jacky.wtf> GPG Key ID: 537A4F904B15268D

+ 16
- 0
README.markdown View File

@@ -3,6 +3,22 @@
3 3
 This monolith serves as the client facing Web application and the API for
4 4
 doing the other bits of work.
5 5
 
6
+## API
7
+The API for IndieMark Scanner is written in Elixir using the Maru
8
+micro Web framework. It's available by hitting `https://indiemark.jacky.wtf/api`
9
+on the publicly available instance.
10
+
11
+## Endpoints
12
+The API exposes a few endpoints that are useful for hitting.
13
+
14
+### PUT `/scans/new`
15
+This starts a new scan request. You have to provide a value of `uri` that'd be
16
+passed to the scanner.
17
+
18
+## Client
19
+The Client for IndieMark Scanner is written using VueJs. It's available
20
+immediately by visiting `https://indiemark.jacky.wtf` on the public instance.
21
+
6 22
 ## About Jacky
7 23
 
8 24
 Hey. I'm [Jacky][], I've written this for my own use but I hope you find it useful.

+ 23
- 12
lib/indiemark/scanner/api.ex View File

@@ -3,34 +3,45 @@ defmodule IndieMark.Scanner.Api do
3 3
   alias IndieMark.Scanner.{Level1, Level2}
4 4
 
5 5
   before do
6
-    plug(Plug.Logger)
7
-    plug(Plug.RequestId)
8 6
     plug(Plug.Head)
7
+    plug(IndieMark.Scanner.Plug.CORS)
8
+
9 9
     plug(
10 10
       Plug.Parsers,
11
-      pass: ["text/*", "application/json"],
11
+      pass: ["*/*"],
12 12
       json_decoder: Poison,
13 13
       parsers: [:urlencoded, :json, :multipart]
14 14
     )
15
-    static_path = Path.join(File.cwd!(), "web/dist")
16
-    plug(Plug.Static, at: "/", from: static_path, gzip: false)
15
+
16
+    plug(
17
+      Plug.Session,
18
+      encryption_salt: 'a_salt',
19
+      key: 'a_key',
20
+      key_length: 64,
21
+      log: 'info',
22
+      signing_salt: 'sign_it_up',
23
+      store: :cookie
24
+    )
25
+
26
+    plug(:fetch_session)
27
+    plug(Plug.CSRFProtection, session_key: :csrf)
28
+  end
29
+
30
+  get :version do
31
+    conn
32
+    |> text(Mix.project()[:version])
17 33
   end
18 34
 
19 35
   resource :scans do
20 36
     params do
21
-      requires :domain, type: String
37
+      requires(:domain, type: String)
22 38
     end
23 39
     put :new do
24 40
       conn
25 41
       |> json(%{
26 42
         level1: Level1.scan(params[:domain]),
27
-        level2: Level2.scan(params[:domain]),
43
+        level2: Level2.scan(params[:domain])
28 44
       })
29 45
     end
30 46
   end
31
-
32
-  get "/" do
33
-    conn
34
-    |> redirect("/index.html", permanent: true)
35
-  end
36 47
 end

+ 11
- 0
lib/indiemark/scanner/plug/cors.ex View File

@@ -0,0 +1,11 @@
1
+defmodule IndieMark.Scanner.Plug.CORS do
2
+  use Corsica.Router,
3
+    origins: "*",
4
+    allow_credentials: true,
5
+    max_age: 600,
6
+    allow_headers: :all,
7
+    allow_methods: :all,
8
+    log: [rejected: :info, invalid: :warn, success: :info]
9
+
10
+  resource "/api/*"
11
+end

+ 55
- 0
lib/indiemark/scanner/router.ex View File

@@ -0,0 +1,55 @@
1
+defmodule IndieMark.Scanner.Router do
2
+  use Maru.Router
3
+  alias IndieMark.Scanner.{Level1, Level2}
4
+
5
+  before do
6
+    plug(Plug.Logger)
7
+    plug(Plug.RequestId)
8
+    plug(IndieMark.Scanner.Plug.CORS)
9
+    plug(Plug.Head)
10
+
11
+    plug(
12
+      Plug.Parsers,
13
+      pass: ["*/*"],
14
+      json_decoder: Poison,
15
+      parsers: [:urlencoded, :json, :multipart]
16
+    )
17
+
18
+    static_path = Path.join(File.cwd!(), "web/dist")
19
+    plug(Plug.Static, at: "/", from: static_path, gzip: true)
20
+
21
+    plug(
22
+      Plug.Session,
23
+      encryption_salt: 'a_salt',
24
+      key: 'a_key',
25
+      key_length: 64,
26
+      log: 'info',
27
+      signing_salt: 'sign_it_up',
28
+      store: :cookie
29
+    )
30
+
31
+    plug(:fetch_session)
32
+    plug(Plug.CSRFProtection, session_key: :csrf)
33
+  end
34
+
35
+  mount Api
36
+  mount Client
37
+
38
+  resource :scans do
39
+    params do
40
+      requires(:domain, type: String)
41
+    end
42
+    put :new do
43
+      conn
44
+      |> json(%{
45
+        level1: Level1.scan(params[:domain]),
46
+        level2: Level2.scan(params[:domain])
47
+      })
48
+    end
49
+  end
50
+
51
+  get "/" do
52
+    conn
53
+    |> redirect("/index.html", permanent: true)
54
+  end
55
+end

+ 1
- 0
mix.exs View File

@@ -38,6 +38,7 @@ defmodule IndieMark.Scanner.MixProject do
38 38
       {:poison, "~> 3.0.0"},
39 39
       {:dns, "~> 2.1.0"},
40 40
       {:floki, "~> 0.20.3"},
41
+      {:corsica, "~> 1.1"}
41 42
     ]
42 43
   end
43 44
 

+ 1
- 0
mix.lock View File

@@ -1,6 +1,7 @@
1 1
 %{
2 2
   "apex": {:hex, :apex, "1.2.1", "297f5dac23fa2a32648b890a0838fce2772114010e0b9ec975cae6021cc5a092", [:mix], [], "hexpm"},
3 3
   "certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
4
+  "corsica": {:hex, :corsica, "1.1.2", "5ad8b9dcbeeda4762d78a57c0c8c2f88e1eef8741508517c98cb79e0db1f107d", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
4 5
   "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
5 6
   "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"},
6 7
   "dns": {:hex, :dns, "2.1.0", "4777fe07ae3060c1d5d75024f05c26d7e11fa701d48a6edb9fc305d24cd12c8c", [:mix], [{:socket, "~> 0.3.13", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm"},

+ 0
- 0
test/indiemark/scanner/application_test.exs View File


+ 10
- 0
test/indiemark/scanner/router_test.exs View File

@@ -0,0 +1,10 @@
1
+defmodule IndieMark.Scanner.ApiTest do
2
+  use ExUnit.Case
3
+  doctest IndieMark.Scanner.Api
4
+  alias IndieMark.Scanner.Api
5
+
6
+  describe "GET /api/version" do
7
+    test "reports version of API" do
8
+    end
9
+  end
10
+end

+ 19
- 0
web/package-lock.json View File

@@ -4323,6 +4323,11 @@
4323 4323
         "es6-symbol": "^3.1.1"
4324 4324
       }
4325 4325
     },
4326
+    "es6-object-assign": {
4327
+      "version": "1.1.0",
4328
+      "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
4329
+      "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw="
4330
+    },
4326 4331
     "es6-symbol": {
4327 4332
       "version": "3.1.1",
4328 4333
       "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
@@ -10925,6 +10930,11 @@
10925 10930
       "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
10926 10931
       "dev": true
10927 10932
     },
10933
+    "promise-polyfill": {
10934
+      "version": "6.1.0",
10935
+      "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz",
10936
+      "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc="
10937
+    },
10928 10938
     "proxy-addr": {
10929 10939
       "version": "2.0.4",
10930 10940
       "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
@@ -12688,6 +12698,15 @@
12688 12698
         }
12689 12699
       }
12690 12700
     },
12701
+    "sweetalert": {
12702
+      "version": "2.1.0",
12703
+      "resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.0.tgz",
12704
+      "integrity": "sha512-9YKj0SvjKyBfRWco50UOsIbXVeifYbxzT9Qda7EsqC01eafHGCSG0IR7g942ufjzt7lnwO8ZZBwr6emXv2fQrg==",
12705
+      "requires": {
12706
+        "es6-object-assign": "^1.1.0",
12707
+        "promise-polyfill": "^6.0.2"
12708
+      }
12709
+    },
12691 12710
     "symbol-observable": {
12692 12711
       "version": "1.2.0",
12693 12712
       "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",

+ 1
- 0
web/package.json View File

@@ -9,6 +9,7 @@
9 9
   },
10 10
   "dependencies": {
11 11
     "normalize.css": "8.0.0",
12
+    "sweetalert": "2.1.0",
12 13
     "typeface-alegreya": "0.0.54",
13 14
     "typeface-alegreya-sans": "0.0.54",
14 15
     "vue": "^2.5.17",

+ 2
- 0
web/src/assets/css/main.scss View File

@@ -34,6 +34,8 @@ p.lead {
34 34
   font-size: 1.5rem;
35 35
 }
36 36
 
37
+.tc { text-align: center; }
38
+
37 39
 h1, h2, h3, h4, h5, h6, blockquote {
38 40
   font-family: var(--font-family-serif);
39 41
 }

+ 1
- 1
web/src/main.js View File

@@ -17,7 +17,7 @@ Vue.use(VueMatomo, {
17 17
   router: router,
18 18
   requireConsent: false,
19 19
   trackInitialView: true
20
-})
20
+});
21 21
 
22 22
 new Vue({
23 23
   router,

+ 3
- 3
web/src/views/Home.vue View File

@@ -1,7 +1,7 @@
1 1
 <template>
2 2
   <section>
3 3
     <form v-on:submit.prevent="testDomain">
4
-      <p class="lead">
4
+      <p class="lead tc">
5 5
         Enter a valid URI that you'd like to scan.
6 6
       </p>
7 7
       <input type="text" v-model="domain" v-model.lazy="domain" />
@@ -41,11 +41,11 @@ export default {
41 41
   data: function() {
42 42
     return {
43 43
       domain: "https://jacky.wtf/",
44
-      resp: null,
44
+      resp: null
45 45
     };
46 46
   },
47 47
   computed: {
48
-    totalScore: function () {
48
+    totalScore: function() {
49 49
       if (this.resp) {
50 50
         return this.resp.level1.score + this.resp.level2.score;
51 51
       }

Loading…
Cancel
Save