diff --git a/Makefile b/Makefile index 404edc5..4f4f419 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,5 @@ .PHONY: build build: - # Build Docker image docker build -t distrust-co . .PHONY: fullclean @@ -18,5 +17,4 @@ _site: build .PHONY: serve serve: build - # Run Docker container with listener for current dir and port mapping docker run --rm -p 0.0.0.0:4000:80 -it distrust-co diff --git a/_config.yml b/_config.yml index 7c43098..7cad44e 100644 --- a/_config.yml +++ b/_config.yml @@ -18,25 +18,23 @@ # You can create any custom variable you would like, and they will be accessible # in the templates via {{ site.myvariable }}. -title: Distrust -email: lance@distrust.co +title: Distrust Disaster Recovery +email: sales@distrust.co description: >- # this means to ignore newlines until "baseurl:" Trust Nothing baseurl: "" # the subpath of your site, e.g. /blog -url: "https://distrust.co" # the base hostname & protocol for your site, e.g. http://example.com +url: "https://dr.distrust.co" # the base hostname & protocol for your site, e.g. http://example.com header_pages: - index.md - about.md - pricing.md -- wizard.md - recovery_policy.md - data_storage.md - q&a.md -- contact.md -style: dark # dark (default), light or hacker -listen_for_clients_preferred_style: false # false (default) or true +style: light +listen_for_clients_preferred_style: true # false (default) or true footer: '2024 Distrust, LLC' diff --git a/_includes/head.html b/_includes/head.html index bf56233..b03aae8 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -2,6 +2,8 @@ + + @@ -11,8 +13,6 @@ {% endif %} - - diff --git a/_includes/header.html b/_includes/header.html index 5049dcb..fe76347 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -3,8 +3,7 @@ +
-
-
-

Quick Start

-
-

- If you are ready to protect your data, you can use - the Wizard which will walk you through the process. -

- Quick Start -
-
-
- -
- -

How it Works

Distrust used the - Quorum Key Management specification to generate + Quorum Key Management specification to generate entropy offline and used it to derive a PGP key which anyone can encrypt to. @@ -65,13 +64,11 @@ Clients may choose to generate their own encryption key, encrypt data, then encrypt that key to the Distrust Disaster Recovery Public - Key. In this way the data is never exposed to + Key. In this way the data is never exposed to Distrust in any form, but the client is responsible for backing up data.

-
-

Security

@@ -97,7 +94,7 @@

Being able to verify the compiler by - bootstrapping it in order to ensure it is not + bootstrapping it in order to ensure it is not capable of injection malicious code at runtime is an essential part of supply chain security - and often ignored. @@ -129,9 +126,7 @@

-
-

The Approach

@@ -147,7 +142,8 @@ you can use our blueprint to set up the system yourself - and we invite you to do so. You can find the documentation on how QKM works - here

+ here +

Most, if not all current commercial backup/disaster @@ -164,7 +160,6 @@ We invite you to question any part of our system.

-
{%- include footer.html -%} diff --git a/_layouts/wizard.html b/_layouts/wizard.html index 31b0fd8..6a26af4 100644 --- a/_layouts/wizard.html +++ b/_layouts/wizard.html @@ -28,44 +28,46 @@ The dates are always interpreted in UTC (Coordinated Universal Time), at 12:00AM of the selected date. - The two dates which are configurable, from_date and upto_date allow for + The two dates which are configurable, from_date and to_date allow for the following configurations: - -

- - - + +

- - + +

- +
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
- -

Please select public keys which can be used for recovery. These keys should be valid public keys - for whichever protocols you would like to use. You may use a mix of protocols. Ensure each file - only has 1 key:

+
+

+ Please select public keys which can be used for recovery. + These keys should be valid public keys for whichever + protocols you would like to use. You may use a mix of + protocols. Ensure each file only has 1 key:

+
+
@@ -142,21 +150,23 @@

- Please select KYC data for individuals who can participate in recovery. - Each person's data should be a `.toml` file. Pictures of front and back - of IDs should be base64 encoded and listed in the id_images array. - The supported ID types are Driver's License, Passport, National Identity Card: + Please select KYC data for individuals who can + participate in recovery. Each person's data should be a + .toml file. Pictures of front and back of IDs should be + base64 encoded and listed in the id_images array. + The supported ID types are Driver's License, Passport, + National Identity Card:

                         
-                        first_name = "John"
-                        last_name = "Doe"
-                        date_of_birth = "1990-01-01"
-                        id_images = ["", "", ...]
-                        country_of_birth = "US"
+                            first_name = "John"
+                            last_name = "Doe"
+                            date_of_birth = "1990-01-01"
+                            id_images = ["", "", ...]
+                            country_of_birth = "US"
                         
-                    
+ @@ -167,10 +177,11 @@

Data Storage

- This part of the policy allows you to select wether you would like - Distrust to fully back up all your data, or to only hold an encryption - key in escrow, in which case you are responsible for redundantly backing up - the encrypted data (learn more here) + This part of the policy allows you to select wether you + would like Distrust to fully back up all your data, or to + only hold an encryption key in escrow, in which case you are + responsible for redundantly backing up the encrypted data + (learn more here)


@@ -193,6 +204,24 @@ + +
+
+ + +

+ Deadman switches can only be used with "key-escrow" mode, + and not "fully managed". If a policy is defined as a deadman + switch, the escrow key will be emailed to the designated + email addresses or posted on the Distrust website, or both, + as preferred. +

+
+
@@ -200,188 +229,13 @@
- +
- - - {%- include footer.html -%} diff --git a/_sass/_dark.scss b/_sass/_dark.scss deleted file mode 100644 index cddd08f..0000000 --- a/_sass/_dark.scss +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Dark theme variables - */ - -:root { - --base-color: #FFFFFF; - --border: solid 2px rgba(219, 219, 219, 0.9); - --selection-background: rgba(219, 219, 219, 0.99); - --selection-text: #000; - --background-color: #04355d; - --text-color: var(--base-color); - --placeholder-color: var(--base-color); - --link-color: var(--base-color); - --code-color-1: #aaaaaa; - --code-color-2: #ffffcc; - --code-color-3: #F00000; - --code-color-4: #F0A0A0; - --code-color-5: #b38aff; - --code-color-6: #5ba711; - --code-color-7: #e4e477; - --code-color-8: #000080; - --code-color-9: #05ca05; - --code-color-10: #888888; - --code-color-11: #555555; - --code-color-12: #800080; - --code-color-13: #00d4d4; - --code-color-14: #00c1c1; - --code-color-15: #ed9d13; - --code-color-16: #1e90ff; - --code-color-17: #800000; - --code-color-18: #bbbbbb; -} diff --git a/_sass/_light.scss b/_sass/_light.scss deleted file mode 100644 index 3515c95..0000000 --- a/_sass/_light.scss +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Base variables - */ - -:root { - --base-color: #000; - --border: dashed 1px rgba(0, 0, 0, 1); - --selection-background: rgba(0, 0, 0, 0.99); - --selection-text: #FFF; - --background-color: #FFF; - --text-color: var(--base-color); - --placeholder-color: var(--base-color); - --link-color: var(--base-color); - --code-color-1: #aaaaaa; - --code-color-2: #ffffcc; - --code-color-3: #F00000; - --code-color-4: #F0A0A0; - --code-color-5: #0000aa; - --code-color-6: #4c8317; - --code-color-7: #aa0000; - --code-color-8: #000080; - --code-color-9: #00aa00; - --code-color-10: #888888; - --code-color-11: #555555; - --code-color-12: #800080; - --code-color-13: #00aaaa; - --code-color-14: #009999; - --code-color-15: #aa5500; - --code-color-16: #1e90ff; - --code-color-17: #800000; - --code-color-18: #bbbbbb; -} diff --git a/_sass/base.scss b/_sass/base.scss index bcfc5f9..d3f3717 100644 --- a/_sass/base.scss +++ b/_sass/base.scss @@ -1,21 +1,127 @@ @charset "utf-8"; -// @import url('https://fonts.googleapis.com/css?family=Rubik:400,700'); -// @import url('Rubik-VariableFont_wght.ttf'); @font-face { font-family: 'Rubik'; src: url('fonts/Rubik-VariableFont_wght.ttf') format('truetype'); } -/** - * Style variables - */ $base-font-family: 'Rubik', monospace !default; $base-font-size: 1.125rem !default; $mobile-font-size: 1.125rem !default; $base-line-height: 1.5 !default; $container-width: 90% !default; -$container-max-width: 1300px !default; +$container-max-width: 1000px !default; + +html { + transition: none !important; +} + +:root { + --base-color: rgba(0, 0, 0, 0.87); + --header-color: black; + --border: dashed 1px rgba(0, 0, 0, 1); + --selection-background: rgba(0, 0, 0, 0.40); + --selection-text: #FFF; + --background-color: #FFF; + --text-color: var(--base-color); + --placeholder-color: var(--base-color); + --link-color: blue; + --navbar-link-color: black; + --navbar-link-hover-color: gray; + --theme-slider-state: translateX(0px); + --code-color-1: #aaaaaa; + --code-color-2: #ffffcc; + --code-color-3: #F00000; +} + + + :root.dark-theme { + --base-color: rgba(255, 255, 255, 0.87); + --header-color: white; + --border: solid 2px rgba(219, 219, 219, 0.9); + --selection-background: rgba(219, 219, 219, 0.99); + --selection-text: #000; + --background-color: #141414; + --text-color: var(--base-color); + --placeholder-color: rgba(0, 0, 0, 0.5); + --link-color: var(--base-color); + --navbar-link-color: white; + --navbar-link-hover-color: gray; + --theme-slider-state: translateX(26px); + /* yoinkt from Material Design 2014, Light Blue A200 */ + --mega-color: #40C4FF; + --code-color-1: #569fe8; + --code-color-2: #ffffcc; + --code-color-3: #F00000; + } + +/* Dark mode */ +@media (prefers-color-scheme: dark) { + :root { + --base-color: rgba(255, 255, 255, 0.87); + --header-color: white; + --border: solid 2px rgba(219, 219, 219, 0.9); + --selection-background: rgba(219, 219, 219, 0.99); + --selection-text: #000; + --background-color: #141414; + --text-color: var(--base-color); + --placeholder-color: rgba(0, 0, 0, 0.5); + --link-color: var(--base-color); + --navbar-link-color: white; + --navbar-link-hover-color: gray; + --theme-slider-state: translateX(26px); + /* yoinkt from Material Design 2014, Light Blue A200 */ + --mega-color: #40C4FF; + --code-color-1: #569fe8; + --code-color-2: #ffffcc; + --code-color-3: #F00000; + } +} + +/* Theme toggle button */ +.switch { + position: relative; + display: inline-block; + width: 60px; + height: 34px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + transition: .4s; + border-radius: 34px; +} + +.slider:before { + position: absolute; + content: ""; + height: 26px; + width: 26px; + left: 4px; + bottom: 4px; + background-color: white; + border-radius: 50%; +} + +input:checked + .slider { + background-color: var(--code-color-1); +} + +input:checked + .slider:before { + transform: var(--theme-slider-state); +} /** * Global @@ -65,7 +171,7 @@ h6 { margin-top: 0px; margin-bottom: 12px; font-weight: bold; - color: var(--text-color); + color: var(--header-color); } p, @@ -78,11 +184,12 @@ ol { a { text-decoration: underline; color: var(--link-color); + transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out; } a:hover { - color: var(--background-color); - background-color: var(--base-color); + color: var(--base-color); + background-color: var(--background-color); transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out; } @@ -103,11 +210,6 @@ a:hover { } p { - /* - word-wrap: break-word; - word-break: break-word; - white-space: pre-wrap; - */ margin-top: 16px; margin-bottom: 16px; } @@ -121,8 +223,9 @@ footer { } header { - margin-top: 24px; + padding: 24px; margin-bottom: 24px; + border-bottom: 1px solid rgba(255, 255, 255, 0.13); } header p { @@ -142,12 +245,18 @@ hr { * Navbar */ .menu-logo { - height: 60px; + height: 48px; +} + + +#home-link { + color: var(--base-color); + background: var(--background-color); + text-decoration: none; } #home-link:hover { - background: none; - text-decoration: none; + color:var(--navbar-link-hover-color); } .header-page-links li:before { @@ -158,11 +267,20 @@ hr { margin: 0px 4px; font-size: 1.1rem; text-decoration: none; + color: var(--navbar-link-color); } .header-page-links a:hover { - background-color: transparent; - color: lightgrey; + color: var(--navbar-link-hover-color); +} + +.left-menu { + display: flex; + align-items: center; +} + +.left-menu img { + display: flex; } .right-menu { @@ -190,7 +308,7 @@ hr { .menu-button::before, .menu-button::after { display: block; - background-color: #fff; + background-color: var(--background-color); position: absolute; height: 4px; width: 30px; @@ -283,22 +401,35 @@ hr { /** * Buttons */ -.action-button { +.button { display: inline-block; padding: 10px 20px 9px 20px; margin-top: 10px; - border-color: white; - border: solid 1px; - color: black; - background-color: white; + color: var(--base-color); + background-color: var(--background-color); + border: 2px solid white; text-decoration: none; + transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out; } -.action-button:hover { - background-color: transparent; - border-color: white; - border: solid 1px; - color: white; +.button:hover { + /* invert */ + background-color: var(--base-color); + color: var(--background-color); + transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out; +} + +/* important button */ +.mega.button { + background-color: var(--mega-color); + color: var(--base-color); + border: 2px solid var(--mega-color); +} + +.mega.button:hover { + /* invert */ + background-color: color-mix(in srgb, var(--mega-color), white 10%); + color: var(--base-color); } .button-container { @@ -344,17 +475,13 @@ hr { * Header/Navigation */ .menu { - border-bottom: var(--border); - margin-bottom: 20px; + /* border-bottom: var(--border); */ display: flex; justify-content: space-between; align-items: center; - padding-bottom: 25px; } .menu ul { - margin-top: 12px; - margin-bottom: 12px; padding-left: 0px; list-style-type: none; text-align: right; @@ -384,12 +511,9 @@ select, textarea { width: 100%; resize: none; - background-color: var(--background-color); - color: var(--text-color); - caret-color: var(--text-color); - font-size: $base-font-size; - font-family: $base-font-family; - line-height: $base-line-height; + background-color: white; + color: black; + caret-color: black; } input, @@ -434,6 +558,50 @@ textarea { vertical-align: top; } +/** + * Contact Form + */ +.required:after { + content: "*"; + color: red; +} + +.form-label { + display: block; + margin-bottom: 5px; +} + +.form-input, +.form-select, +.form-textarea { + width: 100%; + padding: 8px; + margin-bottom: 10px; + height: 40px; +} + +.form-textarea { + height: 100px; +} + +.form-checkbox-container { + display: flex; + flex-direction: column; +} + +.form-submit-button { + padding: 10px 20px; + background-color: #4CAF50; + color: white; + border: none; + cursor: pointer; + height: 40px; +} + +.form-submit-button:hover { + background-color: #45a049; +} + /** * Homepage */ @@ -457,375 +625,18 @@ textarea { } section { - margin-top: 24px; - margin-bottom: 24px; -} - -.extra-spacing { - margin-top: 70px; - margin-bottom: 70px; -} - -.companies { - display: flex; - justify-content: space-between; - align-items: center; - margin: 30px 0px; -} - -.companies div { - width: 27%; - text-align: center; - display: flex; - align-items: center; - justify-content: center; - height: 120px; - border-bottom: 1px solid; -} - -.companies a img { - height: 45px; - filter: grayscale(100%); - text-align: center; -} - -.companies a:hover { - background-color: none; - background: none; - text-decoration: none; + margin-top: 48px; + margin-bottom: 120px; } .text-well { - max-width: 600px; + max-width: 100%; padding-right: 35px; } -/** - * Code and syntax highlighting - */ -.lineno { - color: var(--code-color-1); - margin-right: 15px; -} - -figure.highlight { - margin: 5px 0; -} - -pre { - background-color: var(--background-color); - border: none; - padding: 0; - margin: 0; - overflow: auto; - font-size: $base-font-size; - color: var(--text-color); - line-height: 1.7 !important; - font-family: $base-font-family !important; -} - -.highlight .hll { - background-color: var(--code-color-2); -} - -.highlight .c { - color: var(--code-color-1); - font-style: italic -} - -/* Comment */ -.highlight .err { - color: var(--code-color-3); - background-color: var(--code-color-4); -} - -/* Error */ -.highlight .k { - color: var(--code-color-5); -} - -/* Keyword */ -.highlight .cm { - color: var(--code-color-1); - font-style: italic -} - -/* Comment.Multiline */ -.highlight .cp { - color: var(--code-color-6); -} - -/* Comment.Preproc */ -.highlight .c1 { - color: var(--code-color-1); - font-style: italic -} - -/* Comment.Single */ -.highlight .cs { - color: var(--code-color-5); - font-style: italic -} - -/* Comment.Special */ -.highlight .gd { - color: var(--code-color-7); -} - -/* Generic.Deleted */ -.highlight .ge { - font-style: italic -} - -/* Generic.Emph */ -.highlight .gr { - color: var(--code-color-7); -} - -/* Generic.Error */ -.highlight .gh { - color: var(--code-color-8); - font-weight: bold -} - -/* Generic.Heading */ -.highlight .gi { - color: var(--code-color-9); -} - -/* Generic.Inserted */ -.highlight .go { - color: var(--code-color-10); -} - -/* Generic.Output */ -.highlight .gp { - color: var(--code-color-11); -} - -/* Generic.Prompt */ -.highlight .gs { - font-weight: bold -} - -/* Generic.Strong */ -.highlight .gu { - color: var(--code-color-12); - font-weight: bold -} - -/* Generic.Subheading */ -.highlight .gt { - color: var(--code-color-7); -} - -/* Generic.Traceback */ -.highlight .kc { - color: var(--code-color-5); -} - -/* Keyword.Constant */ -.highlight .kd { - color: var(--code-color-5); -} - -/* Keyword.Declaration */ -.highlight .kn { - color: var(--code-color-5); -} - -/* Keyword.Namespace */ -.highlight .kp { - color: var(--code-color-5); -} - -/* Keyword.Pseudo */ -.highlight .kr { - color: var(--code-color-5); -} - -/* Keyword.Reserved */ -.highlight .kt { - color: var(--code-color-13); -} - -/* Keyword.Type */ -.highlight .m { - color: var(--code-color-14); -} - -/* Literal.Number */ -.highlight .s { - color: var(--code-color-15); -} - -/* Literal.String */ -.highlight .na { - color: var(--code-color-16); -} - -/* Name.Attribute */ -.highlight .nb { - color: var(--code-color-13); -} - -/* Name.Builtin */ -.highlight .nc { - color: var(--code-color-9); - text-decoration: underline -} - -/* Name.Class */ -.highlight .no { - color: var(--code-color-7); -} - -/* Name.Constant */ -.highlight .nd { - color: var(--code-color-10); -} - -/* Name.Decorator */ -.highlight .ni { - color: var(--code-color-17); - font-weight: bold -} - -/* Name.Entity */ -.highlight .nf { - color: var(--code-color-9); -} - -/* Name.Function */ -.highlight .nn { - color: var(--code-color-13); - text-decoration: underline -} - -/* Name.Namespace */ -.highlight .nt { - color: var(--code-color-16); - font-weight: bold -} - -/* Name.Tag */ -.highlight .nv { - color: var(--code-color-7); -} - -/* Name.Variable */ -.highlight .ow { - color: var(--code-color-5); -} - -/* Operator.Word */ -.highlight .w { - color: var(--code-color-18); -} - -/* Text.Whitespace */ -.highlight .mf { - color: var(--code-color-14); -} - -/* Literal.Number.Float */ -.highlight .mh { - color: var(--code-color-14); -} - -/* Literal.Number.Hex */ -.highlight .mi { - color: var(--code-color-14); -} - -/* Literal.Number.Integer */ -.highlight .mo { - color: var(--code-color-14); -} - -/* Literal.Number.Oct */ -.highlight .sb { - color: var(--code-color-15); -} - -/* Literal.String.Backtick */ -.highlight .sc { - color: var(--code-color-15); -} - -/* Literal.String.Char */ -.highlight .sd { - color: var(--code-color-15); -} - -/* Literal.String.Doc */ -.highlight .s2 { - color: var(--code-color-15); -} - -/* Literal.String.Double */ -.highlight .se { - color: var(--code-color-15); -} - -/* Literal.String.Escape */ -.highlight .sh { - color: var(--code-color-15); -} - -/* Literal.String.Heredoc */ -.highlight .si { - color: var(--code-color-15); -} - -/* Literal.String.Interpol */ -.highlight .sx { - color: var(--code-color-15); -} - -/* Literal.String.Other */ -.highlight .sr { - color: var(--code-color-14); -} - -/* Literal.String.Regex */ -.highlight .s1 { - color: var(--code-color-15); -} - -/* Literal.String.Single */ -.highlight .ss { - color: var(--code-color-5); -} - -/* Literal.String.Symbol */ -.highlight .bp { - color: var(--code-color-13); -} - -/* Name.Builtin.Pseudo */ -.highlight .vc { - color: var(--code-color-7); -} - -/* Name.Variable.Class */ -.highlight .vg { - color: var(--code-color-7); -} - -/* Name.Variable.Global */ -.highlight .vi { - color: var(--code-color-7); -} - -/* Name.Variable.Instance */ -.highlight .il { - color: var(--code-color-14); -} /* Literal.Number.Integer.Long */ - .hide { display: none; width: 100%; @@ -835,66 +646,6 @@ pre { display: inline-block; } - -/** - * Carousel - */ - -.carousel-container { - padding-left: 80px; -} - -#carousel { - display: flex; - flex-direction: column; - align-items: center; - overflow: hidden; - height: 320px; - padding-left: 100px; - position: relative; -} - -.carousel-item { - display: flex; - justify-content: center; - align-items: center; - max-width: 400px; - height: 80px; - width: 100%; - font-size: 16px; - opacity: 0.5; - margin: 5px 0; - position: absolute; - left: 0; - right: 0; - transition: transform 1s ease, font-size 1s ease, opacity 1s ease; - transform-origin: center; - visibility: hidden; - overflow: hidden; -} - -.carousel-link { - text-align: left; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - overflow: hidden; - text-overflow: ellipsis; - line-height: 1.2; - max-height: 2.4em; - width: 100%; - margin: 0 10px; - white-space: normal; -} - -.carousel-item.active { - transform: translateY(0) scale(1.2); - font-size: 20px; - opacity: 1; - visibility: visible; -} -/** end carousel */ - /** * Blog */ @@ -934,6 +685,104 @@ body { margin-top: 10px; } + +.timeline { + position: relative; + width: 100%; + height: 50px; + display: flex; + align-items: center; +} + +.segment { + height: 5px; + background-color: white; + width: 33.33%; +} + +.active-segment { + background-color: #33ff57; +} + +.marker { + height: 30px; + position: absolute; + width: 120px; + border-left: 2px solid black; +} + +/** + * timeline + */ + +#to-date, +#from-date { + width: 100%; + text-align: center; +} + +#from-date-arrow, +#to-date-arrow { + font-size: 25px; +} + +.date-container { + width: 120px; + position: absolute; + margin-left: -60px; + margin-top: -5px; + text-align: center; +} + +.from-date-container { + left: 33.33%; +} + +.to-date-container { + left: 66.66%; +} + +.marker-1 { + left: 33.33%; +} + +.marker-2 { + left: 66.66%; +} + + +/** + * wizard + */ +.hidden { + display: none; +} + +input, +select, +textarea, +textarea::-webkit-input-placeholder { + border: 1px solid white; +} + +#wizard-container { + border: 1px solid white; + border-radius: 20px; + padding: 30px; +} + +.divider { + color: white; + margin: 50px 0px; +} + +#generated-policy-form { + height: 400px; + padding: 30px; + margin-top: 30px; + border-radius: 20px; +} + /** * media queries */ @@ -970,4 +819,4 @@ body { padding-top: 50px; padding-left: 10px; } -} +} \ No newline at end of file diff --git a/assets/js/carousel-items.json b/assets/js/carousel-items.json deleted file mode 100644 index b20e831..0000000 --- a/assets/js/carousel-items.json +++ /dev/null @@ -1,122 +0,0 @@ -[ - { - "link": "https://www.wired.com/story/the-untold-story-of-solarwinds-the-boldest-supply-chain-hack-ever/", - "description": "SolarWind: The Untold Story of the Boldest Supply-Chain Hack Ever" - }, - { - "link": "https://www.theverge.com/2018/4/24/17275982/myetherwallet-hack-bgp-dns-hijacking-stolen-ethereum", - "description": "Hackers emptied Ethereum wallets by breaking the basic infrastructure of the internet" - }, - { - "link": "https://milksad.info/", - "description": "A practical explanation of how weak entropy can ruin your day - and your savings." - }, - { - "link": "https://thehackerblog.com/zero-days-without-incident-compromising-angular-via-expired-npm-publisher-email-domains-7kZplW4x/", - "description": "Compromising Angular via Expired npm Publisher Email Domains" - }, - { - "link": "https://blog.ryotak.net/post/homebrew-security-incident-en/", - "description": "Remote code execution in Homebrew by compromising the official Cask repository" - }, - { - "link": "https://gizmodo.com/u-s-federal-investigators-are-reportedly-looking-into-1846707144link4", - "description": "U.S. Federal Investigators Are Reportedly Looking Into Codecov Security Breach, Undetected for Months" - }, - { - "link": "https://www.bleepingcomputer.com/news/security/big-sabotage-famous-npm-package-deletes-files-to-protest-ukraine-war/", - "description": "BIG sabotage: Famous npm package deletes files to protest Ukraine war" - }, - { - "link": "https://certitude.consulting/blog/en/invisible-backdoor/", - "description": "The Invisible JavaScript Backdoor" - }, - { - "link": "https://thehackernews.com/2022/06/multiple-backdoored-python-libraries.html?m=1", - "description": "Multiple Backdoored Python Libraries Caught Stealing AWS Secrets and Keys" - }, - { - "link": "https://www.wired.com/story/3cx-supply-chain-attack-times-two/", - "description": "The Huge 3CX Breach Was Actually 2 Linked Supply Chain Attacks" - }, - { - "link": "https://www.zdnet.com/article/iota-cryptocurrency-shuts-down-entire-network-after-wallet-hack/", - "description": "IOTA cryptocurrency shuts down entire network after wallet hack " - }, - { - "link": "https://arstechnica.com/information-technology/2021/02/supply-chain-attack-that-fooled-apple-and-microsoft-is-attracting-copycats/", - "description": "New type of supply-chain attack hit Apple, Microsoft and 33 other companies" - }, - { - "link": "https://www.bankinfosecurity.com/crypto-exchange-klayswap-loses-19m-after-bgp-hijack-a-18518", - "description": "Crypto Exchange KLAYswap Loses $1.9M After BGP Hijack" - }, - { - "link": "https://www.businessinsider.com/kidnapped-crypto-exec-released-after-paying-1-million-bitcoin-ransom-2017-12", - "description": "A kidnapped crypto executive was reportedly released after paying a $1 million bitcoin ransom" - }, - { - "link": "https://www.independent.co.uk/tech/bitcoin-robbery-torture-cryptocurrency-netherlands-a8807986.html", - "description": "Bitcoin trader brutally tortured with drill in cryptocurrency robbery" - }, - { - "link": "https://www.vice.com/en/article/ne4pvg/police-in-ottawa-canada-charged-a-teen-with-armed-bitcoin-robbery-are-hunting-two-suspects", - "description": "Three Armed Men Attempted to Rob a Bitcoin Exchange In Canada" - }, - { - "link": "https://www.birminghammail.co.uk/news/midlands-news/watch-masked-raiders-hold-up-16599570", - "description": "Watch - Masked raiders hold up Bitcoin Exchange store in Sparkhill in front of dozens of witnesses" - }, - { - "link": "https://www.nzherald.co.nz/nz/crypto-heist-raiders-steal-safe-containing-4m-in-cryptocurrency-from-westmere-home/PI3L5LMS6PCSVABJDYSW5O4YGA/", - "description": "Crypto heist: Raiders steal safe containing $4m in cryptocurrency from Westmere home" - }, - { - "link": "https://www.computerworld.com/article/2538534/data-center-robbery-leads-to-new-thinking-on-security.html", - "description": "Data center robbery leads to new thinking on security" - }, - { - "link": "https://www.thirdsector.co.uk/plan-uk-alerts-supporters-theft-computer-servers-its-offices/management/article/1375208", - "description": "Plan UK alerts supporters to theft of computer servers from its offices" - }, - { - "link": "https://www.pcmag.com/news/vudu-resets-passwords-after-user-data-stolen-in-burglary", - "description": "Vudu Resets Passwords After User Data Stolen in Burglary" - }, - { - "link": "https://finance.yahoo.com/news/hackers-scored-data-center-logins-020028440.html", - "description": "Hackers Scored Data Center Logins for Some of the World's Biggest Companies" - }, - { - "link": "https://www.cbsnews.com/news/nsa-broke-into-yahoo-and-google-data-centers-around-world-report-says/", - "description": "NSA broke into Yahoo and Google data centers around world, report says" - }, - { - "link": "https://www.vice.com/en/article/3kxy4k/high-tech-japanese-hotel-service-robots-easily-hackable", - "description": "High-Tech Japanese Hotel Finds Out Its Service Robots Are Easily Hackable" - }, - { - "link": "https://www.washingtonpost.com/news/innovations/wp/2017/07/21/how-a-fish-tank-helped-hack-a-casino/", - "description": "How a fish tank helped hack a casino" - }, - { - "link": "https://www.wsj.com/articles/fraudsters-use-ai-to-mimic-ceos-voice-in-unusual-cybercrime-case-11567157402", - "description": "Fraudsters Used AI to Mimic CEO's Voice in Unusual Cybercrime Case" - }, - { - "link": "https://www.forbes.com/sites/iainmartin/2023/08/21/blockchain-capitals-bart-stephens-lost-63-million-in-sim-swap-crypto-hack/?sh=6cc4576bf74c", - "description": "Blockchain Capital's Bart Stephens Lost $6.3 Million In SIM-Swap Crypto Hack" - }, - { - "link": "https://www.wsj.com/articles/he-thought-his-phone-was-secure-then-he-lost-24-million-to-hackers-11573221600", - "description": "He Thought His Phone Was Secure; Then He Lost $24 Million to Hackers" - }, - { - "link": "https://arstechnica.com/information-technology/2018/02/tesla-cloud-resources-are-hacked-to-run-cryptocurrency-mining-malware/", - "description": "Tesla cloud resources are hacked to run cryptocurrency-mining malware" - }, - { - "link": "https://www.wired.com/story/sea-turtle-dns-hijacking/", - "description": "Cyberspies Hijacked the Internet Domains of Entire Countries" - } -] diff --git a/assets/js/main.js b/assets/js/main.js index c99fe57..1500365 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -9,57 +9,335 @@ collapsibleButton.addEventListener("click", function () { } }); -document.addEventListener('DOMContentLoaded', function () { - fetch('../assets/js/carousel-items.json') - .then(response => response.json()) - .then(data => { - createCarouselItems(data); - initializeCarousel(); - }) - .catch(error => console.error('Error loading JSON:', error)); +// Toggle theme +const toggleButton = document.getElementById('theme-toggle'); +const htmlElement = document.documentElement; + +function applyTheme() { + const savedTheme = localStorage.getItem('theme'); + if (savedTheme === 'dark') { + toggleButton.checked = true; + htmlElement.classList.add('dark-theme'); + } else { + htmlElement.classList.remove('dark-theme'); + } +} + +toggleButton.addEventListener('click', () => { + if (htmlElement.classList.contains('dark-theme')) { + htmlElement.classList.remove('dark-theme'); + localStorage.setItem('theme', 'light'); + } else { + htmlElement.classList.add('dark-theme'); + localStorage.setItem('theme', 'dark'); + } }); -function createCarouselItems(items) { - const carousel = document.querySelector('#carousel'); - items.forEach(item => { - const itemDiv = document.createElement('div'); - itemDiv.className = 'carousel-item' +// Load the saved theme on page load +window.onload = () => { + console.log('ih') + // applyTheme(); + resetFormFields() +}; - const link = document.createElement('a'); - link.className = 'carousel-link'; - link.href = item.link; - link.target = '_blank'; - link.rel = 'noopener noreferrer'; - const linkText = document.createTextNode(item.description); - link.appendChild(linkText); - itemDiv.appendChild(link); - carousel.appendChild(itemDiv); +function resetFormFields() { + const form = document.getElementById('wizard-container'); + form.reset(); + + const policy_field = document.getElementById('policy'); + policy_field.reset(); +} + +function readFileAsText(file) { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + + reader.onload = function (e) { + resolve(e.target.result); + }; + + reader.onerror = function (e) { + reject(new Error(`Error reading file ${file.name}: ${e.target.error.message}`)); + }; + + return reader.readAsText(file); }); } -function initializeCarousel() { - const carousel = document.querySelector('#carousel'); - const items = Array.from(carousel.children); - const totalItems = items.length; - const middleIndex = Math.floor(totalItems / 2); - let currentIndex = -middleIndex; +async function extractValues() { + const policy = {} - function cycleItems() { - currentIndex = (currentIndex - 1 + totalItems) % totalItems; - updateCarouselItems(); + const policyValidToDateEl = document.getElementById('policy_valid_to_date'); + const policyValidToDate = policyValidToDateEl.value.replace(/-/g, "/"); + if (policyValidToDate) { + policy.policy_valid_to_date = policyValidToDate; + console.log(policyValidToDate); } - function updateCarouselItems() { - items.forEach((item, index) => { - let positionIndex = (currentIndex + index + totalItems) % totalItems; - let offset = positionIndex - middleIndex; - item.style.transform = `translateY(${offset * 100}%)`; - item.classList.toggle('active', positionIndex === middleIndex); - item.style.visibility = 'visible'; - }); + const policyValidAfterDateEl = document.getElementById('policy_valid_after_date'); + const policyValidAfterDate = policyValidAfterDateEl.value.replace(/-/g, "/"); + if (policyValidAfterDate) { + policy.policy_valid_after_date = policyValidAfterDate; + console.log(policyValidAfterDate); } - updateCarouselItems(); - setInterval(cycleItems, 7000); -} \ No newline at end of file + const policyMutableLl = document.getElementById('policy_mutable'); + const policyMutable = policyMutableLl.value; + if (policyMutable) { + policy.policy_mutable = policyMutable; + console.log(policyMutable); + } + + const remoteAvailableEl = document.getElementById('remote_available'); + const remoteAvailable = remoteAvailableEl.value; + if (remoteAvailable) { + policy.remote_available = remoteAvailable; + console.log(remoteAvailable); + } + + const remoteThresholdEl = document.getElementById('remote_threshold'); + const remoteThreshold = remoteThresholdEl.value; + if (remoteThreshold) { + policy.remote_threshold = remoteThreshold; + console.log(remoteThreshold); + } + + const pubKeysEl = document.getElementById('pub_keys'); + const pubKeys = pubKeysEl.files; + + let pubKeyData = []; + for (let i = 0; i < pubKeys.length; i++) { + const pubKeyFile = pubKeys[i]; + const fileText = await readFileAsText(pubKeyFile); + pubKeyData.push(fileText); + } + if (pubKeyData.length) { + policy.pub_keys = pubKeyData; + console.log(pubKeys); + } + + const kycAvailableEl = document.getElementById('kyc_available'); + const kycAvailable = kycAvailableEl.value; + if (kycAvailable) { + policy.kyc_available = kycAvailable; + console.log(kycAvailable); + } + + const kycThresholdEl = document.getElementById('kyc_threshold'); + const kycThreshold = kycThresholdEl.value; + if (kycThreshold) { + policy.kyc_threshold = kycThreshold; + console.log(kycThreshold); + } + + const kycDataEl = document.getElementById('kyc_data'); + const kycData = kycDataEl.files; + if (kycData) { + policy.kyc_data = kycData; + console.log(kycData); + } + + const dataStorageEl = document.getElementById('data_storage'); + const dataStorage = dataStorageEl.value; + if (dataStorage) { + policy.data_storage = dataStorage; + console.log(dataStorage) + } + + const multiRuleRequirementEl = document.getElementById('multi_rule_requirement'); + const multiRuleRequirement = multiRuleRequirementEl.value; + if (multiRuleRequirement) { + policy.multi_rule_requirement = multiRuleRequirement; + console.log(multiRuleRequirement); + } + + return policy; +} + +async function generatePolicy(event) { + event.preventDefault() + const policyValues = extractValues(); + + const tomlPolicy = objectToTOML(policyValues); + console.log(tomlPolicy); + + const policyTextEl = document.getElementById('policy'); + policyTextEl.value = toml_policy; +} + +function validateThreshold(threshold) { + const regex = /^\d+\/\d+$/; + const valid = regex.test(threshold); + let res = { + threshold, + }; + + console.log('threshold', threshold) + if (valid) { + const numbers = threshold.split('/'); + console.log('numbers', numbers) + if (Number(numbers[0]) > Number(numbers[1])) { + res.error = "Error: first number has to be lesser than second."; + } else { + return res; + } + } else { + res.error = "Error: invalid threshold value. Use n/m format where n < m" + } + + return res; +} + +function objectToTOML(obj, indent = '') { + let toml = ''; + + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + const value = obj[key]; + + if (typeof value === 'object' && !Array.isArray(value)) { + toml += `${indent}[${key}]\n`; + toml += objectToTOML(value, `${indent} `); + } else if (Array.isArray(value)) { + toml += `${indent}${key} = [${value.map(v => JSON.stringify(v)).join(', ')}]\n`; + } else { + toml += `${indent}${key} = ${JSON.stringify(value)}\n`; + } + } + } + + return toml; +} + +function clearSegments() { + const segmentLeft = document.getElementById('segment-left'); + const segmentMiddle = document.getElementById('segment-middle'); + const segmentRight = document.getElementById('segment-right'); + + segmentLeft.classList.remove('active-segment'); + segmentMiddle.classList.remove('active-segment'); + segmentRight.classList.remove('active-segment'); + + const fromDateArrow = document.getElementById('from-date-arrow'); + const toDateArrow = document.getElementById('to-date-arrow'); + + fromDateArrow.innerText = ""; + toDateArrow.innerText = ""; +} + +function colorSegment(from_date, to_date) { + clearSegments(); + + const segmentLeft = document.getElementById('segment-left'); + const segmentMiddle = document.getElementById('segment-middle'); + const segmentRight = document.getElementById('segment-right'); + + const fromDateArrow = document.getElementById('from-date-arrow'); + const toDateArrow = document.getElementById('to-date-arrow'); + + if (from_date && !to_date) { + segmentMiddle.classList.add('active-segment'); + segmentRight.classList.add('active-segment'); + + fromDateArrow.innerText = '→'; + } else if (!from_date && to_date) { + segmentLeft.classList.add('active-segment'); + segmentMiddle.classList.add('active-segment'); + + toDateArrow.innerText = '←'; + } else if (from_date && to_date) { + const fromDateTyped = new Date(from_date); + const toDateTyped = new Date(to_date); + if (fromDateTyped < toDateTyped) { + segmentMiddle.classList.add('active-segment'); + + fromDateArrow.innerText = '→'; + toDateArrow.innerText = '←'; + } else if (fromDateTyped > toDateTyped) { + segmentLeft.classList.add('active-segment'); + segmentRight.classList.add('active-segment'); + + fromDateArrow.innerText = '←'; + toDateArrow.innerText = '→'; + } else { + clearSegments(); + } + } else { + clearSegments(); + } +} + +// TODO: fix listeners to only activate if on the correct + +const toDatePicker = document.getElementById('policy_valid_to_date'); +const fromDatePicker = document.getElementById('policy_valid_after_date'); +const fromDateMarker = document.getElementById('from_date'); +const toDateMarker = document.getElementById('to_date'); + +fromDatePicker.addEventListener('change', function () { + fromDateMarker.innerText = fromDatePicker.value; + toDateMarker.innerText = toDatePicker.value; + + let from_value = fromDatePicker.value; + let to_value = toDatePicker.value; + + colorSegment(from_value, to_value); +}); + +toDatePicker.addEventListener('change', function () { + fromDateMarker.innerText = fromDatePicker.value; + toDateMarker.innerText = toDatePicker.value; + + let fromValue = fromDatePicker.value; + let toValue = toDatePicker.value; + + colorSegment(fromValue, toValue); +}); + +let remoteAvailableEl = document.getElementById('remote_available'); +remoteAvailableEl.addEventListener('input', function () { + let currentValue = remoteAvailableEl.value; + let remoteAvailableContainer = document.getElementById('remote_available_container'); + if (currentValue == 'true') { + remoteAvailableContainer.classList.remove('hidden'); + } else { + remoteAvailableContainer.classList.add('hidden'); + } +}); + +const remoteThresholdEl = document.getElementById('remote_threshold'); +remoteThresholdEl.addEventListener('input', function () { + const remoteThresholdErrorEl = document.getElementById('remote_threshold_error'); + remoteThresholdErrorEl.innerText = ""; + const currentValue = remoteThresholdEl.value; + + const thresholdRes = validateThreshold(currentValue) + if (thresholdRes.error) { + remoteThresholdErrorEl.innerText = thresholdRes.error; + } +}); + +const pubKeysErrorEl = document.getElementById('pub_keys_error'); +const pubKeys = document.getElementById('pub_keys') +pubKeys.addEventListener('change', function () { + pubKeysErrorEl.innerText = ""; + const res = validateThreshold(remoteThresholdEl.value); + console.log(res, remoteThresholdEl) + if (pubKeys.files.length < res.threshold.split('/')[1] || !res || !res.threshold) { + console.log('uhoh') + pubKeysErrorEl.innerText = "Please select a valid threshold"; + pubKeys.value = ""; + } +}); + +let kycAvailableEl = document.getElementById('kyc_available'); +kycAvailableEl.addEventListener('input', function () { + let currentValue = kycAvailableEl.value; + let remoteAvailableContainer = document.getElementById('kyc_available_container'); + if (currentValue == 'true') { + remoteAvailableContainer.classList.remove('hidden'); + } else { + remoteAvailableContainer.classList.add('hidden'); + } +}); \ No newline at end of file