From ff28faa2227d0c0466cd9f370e0a0227fbe7f4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Szab=C3=B3?= <25702868+szabodanika@users.noreply.github.com> Date: Mon, 26 Sep 2022 11:53:54 +0000 Subject: [PATCH 01/92] Update README.MD --- README.MD | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.MD b/README.MD index 2fb6af4..0d0aea4 100644 --- a/README.MD +++ b/README.MD @@ -6,7 +6,7 @@ ![Build](https://github.com/szabodanika/microbin/actions/workflows/rust.yml/badge.svg) ![crates.io](https://img.shields.io/crates/v/microbin.svg) - +[![Docker Image](https://github.com/szabodanika/microbin/actions/workflows/docker.yml/badge.svg)](https://github.com/szabodanika/microbin/actions/workflows/docker.yml) MicroBin is a super tiny, feature rich, configurable, self-contained and self-hosted paste bin web application. It is very easy to set up and use, and will only require a few megabytes of memory and disk storage. It takes only a couple minutes to set it up, why not give it a try now? @@ -121,9 +121,9 @@ cargo build --release ./target/release/microbin -p 80 ``` -### Building Docker Image +### Docker -MicroBin includes a Dockerfile. To build the image, follow these steps: +The official automated docker images are available on [Docker Hub at danielszabo99/microbin](https://hub.docker.com/repository/docker/danielszabo99/microbin). Alternatively you can also build an image yourself, following the steps below: ``` git clone https://github.com/szabodanika/microbin.git From d36472bcac31c0fb3e56ab3b390df35f4661d466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Szab=C3=B3?= <25702868+szabodanika@users.noreply.github.com> Date: Mon, 26 Sep 2022 12:10:01 +0000 Subject: [PATCH 02/92] Update README.MD --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index 0d0aea4..1aaec2c 100644 --- a/README.MD +++ b/README.MD @@ -6,7 +6,7 @@ ![Build](https://github.com/szabodanika/microbin/actions/workflows/rust.yml/badge.svg) ![crates.io](https://img.shields.io/crates/v/microbin.svg) -[![Docker Image](https://github.com/szabodanika/microbin/actions/workflows/docker.yml/badge.svg)](https://github.com/szabodanika/microbin/actions/workflows/docker.yml) +[![Docker Image](https://github.com/szabodanika/microbin/actions/workflows/docker.yml/badge.svg)](https://hub.docker.com/r/danielszabo99/microbin) MicroBin is a super tiny, feature rich, configurable, self-contained and self-hosted paste bin web application. It is very easy to set up and use, and will only require a few megabytes of memory and disk storage. It takes only a couple minutes to set it up, why not give it a try now? From 05ad1d46c16c73007dd1c6025c769547c1a91945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Szab=C3=B3?= <25702868+szabodanika@users.noreply.github.com> Date: Tue, 27 Sep 2022 16:19:41 +0000 Subject: [PATCH 03/92] Update README.MD Updated docker volume path according to 08871e1. Fixes #55 --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index 1aaec2c..09bd132 100644 --- a/README.MD +++ b/README.MD @@ -141,7 +141,7 @@ services: ports: - "80:8080" volumes: - - ./microbin-data:/usr/local/bin/pasta_data + - ./microbin-data:/app/pasta_data ``` To pass command line arguments you must edit the Dockerfile and change the CMD line. In this example we add the syntax highlighting option and enable private pastas: From 2322c6713e2f113d7389aec32ff5075ff5bcbe6a Mon Sep 17 00:00:00 2001 From: Jonas Friedmann Date: Tue, 27 Sep 2022 20:09:44 +0200 Subject: [PATCH 04/92] Fix Docker repository link --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index 09bd132..18006f6 100644 --- a/README.MD +++ b/README.MD @@ -123,7 +123,7 @@ cargo build --release ### Docker -The official automated docker images are available on [Docker Hub at danielszabo99/microbin](https://hub.docker.com/repository/docker/danielszabo99/microbin). Alternatively you can also build an image yourself, following the steps below: +The official automated docker images are available on [Docker Hub at danielszabo99/microbin](https://hub.docker.com/r/danielszabo99/microbin). Alternatively you can also build an image yourself, following the steps below: ``` git clone https://github.com/szabodanika/microbin.git From 6cea6262b82b5f61a41aec6bd620124ddbd3beb3 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 30 Sep 2022 21:08:02 -0800 Subject: [PATCH 05/92] init git ignore --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..73fab07 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb From 8223dd497334179c65e08d26ffe9159100d6b739 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 30 Sep 2022 21:11:16 -0800 Subject: [PATCH 06/92] export port 8080 in dockerfile --- Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Dockerfile b/Dockerfile index 21e31e9..3e10f7a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,4 +30,7 @@ COPY --from=build \ /app/target/release/microbin \ /usr/bin/microbin +# Expose webport used for the webserver to the docker runtime +EXPOSE 8080 + ENTRYPOINT ["microbin"] \ No newline at end of file From 1e8b17bb8935b7d0ec1c4cef9d3a34d355a18629 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 30 Sep 2022 21:37:26 -0800 Subject: [PATCH 07/92] add copy button to viewer --- templates/pasta.html | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/templates/pasta.html b/templates/pasta.html index 879c948..adf52cb 100644 --- a/templates/pasta.html +++ b/templates/pasta.html @@ -16,13 +16,31 @@ {{pasta.id_as_animals()}}
-
- {% if args.highlightsyntax %} -
{{pasta.content_syntax_highlighted()}}
- {%- else %} -
{{pasta.content_not_highlighted()}}
- {%- endif %} +
+ +
+ {% if args.highlightsyntax %} +
{{pasta.content_syntax_highlighted()}}
+ {%- else %} +
{{pasta.content_not_highlighted()}}
+ {%- endif %} +
+ + + {% include "footer.html" %} From cc504f781e34570aeecb88ec7c6fdfb9a60c3be0 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 30 Sep 2022 21:51:52 -0800 Subject: [PATCH 08/92] add favicon resource --- templates/favicon.svg | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 templates/favicon.svg diff --git a/templates/favicon.svg b/templates/favicon.svg new file mode 100644 index 0000000..f65dd39 --- /dev/null +++ b/templates/favicon.svg @@ -0,0 +1,3 @@ + + + From ef5d07392b19bb17a1f331b16e357bd13e2f72ba Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 30 Sep 2022 21:52:08 -0800 Subject: [PATCH 09/92] add in template and as static resource --- src/endpoints/static_resources.rs | 13 +++++++++++++ templates/header.html | 1 + 2 files changed, 14 insertions(+) diff --git a/src/endpoints/static_resources.rs b/src/endpoints/static_resources.rs index 9a5318e..728d617 100644 --- a/src/endpoints/static_resources.rs +++ b/src/endpoints/static_resources.rs @@ -8,6 +8,12 @@ struct WaterCSS<'a> { _marker: PhantomData<&'a ()>, } +#[derive(Template)] +#[template(path = "favicon.svg", escape = "none")] +struct Favicon<'a> { + _marker: PhantomData<&'a ()>, +} + #[get("/static/{resource}")] pub async fn static_resources(resource_id: web::Path) -> HttpResponse { match resource_id.into_inner().as_str() { @@ -18,6 +24,13 @@ pub async fn static_resources(resource_id: web::Path) -> HttpResponse { .render() .unwrap(), ), + "favicon.svg" => HttpResponse::Ok().content_type("image/svg+xml").body( + Favicon { + _marker: Default::default(), + } + .render() + .unwrap(), + ), _ => HttpResponse::NotFound().content_type("text/html").finish(), } } diff --git a/templates/header.html b/templates/header.html index 37d2de0..46bb7dc 100644 --- a/templates/header.html +++ b/templates/header.html @@ -9,6 +9,7 @@ + {% if !args.pure_html %} {%- endif %} From e17b26994f56b251057ede5ed483fe70489eaaae Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 30 Sep 2022 22:10:43 -0800 Subject: [PATCH 10/92] add cli args to disable file upload --- src/args.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/args.rs b/src/args.rs index 577fa0f..1472391 100644 --- a/src/args.rs +++ b/src/args.rs @@ -59,4 +59,7 @@ pub struct Args { #[clap(long, env="MICROBIN_WIDE")] pub wide: bool, + + #[clap(short, long, env="MICROBIN_NO_FILE_UPLOAD")] + pub no_file_upload: bool, } \ No newline at end of file From fc3998243bdd3fa0725ed3a854ebe39034b3c15b Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 30 Sep 2022 22:11:03 -0800 Subject: [PATCH 11/92] ignore file processing if no_file_upload is true --- src/endpoints/create.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/endpoints/create.rs b/src/endpoints/create.rs index 8c8b1a3..40efa41 100644 --- a/src/endpoints/create.rs +++ b/src/endpoints/create.rs @@ -106,6 +106,10 @@ pub async fn create( continue; } "file" => { + if ARGS.no_file_upload { + continue; + } + let path = field.content_disposition().get_filename(); let path = match path { From 82c30ce6cd16843a0d1e75f25664245a6635f7a2 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 30 Sep 2022 22:11:25 -0800 Subject: [PATCH 12/92] conditionally render file upload --- templates/index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/index.html b/templates/index.html index e1c4ef7..943de85 100644 --- a/templates/index.html +++ b/templates/index.html @@ -59,11 +59,13 @@ {%- endif %} + {% if !args.no_file_upload %}

+ {% endif %}

From 0b5dea5dd1510cff4d1652be29f575c4bd70e948 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 30 Sep 2022 22:12:24 -0800 Subject: [PATCH 13/92] add flag to docs --- README.MD | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.MD b/README.MD index 18006f6..b64e4c4 100644 --- a/README.MD +++ b/README.MD @@ -11,8 +11,8 @@ MicroBin is a super tiny, feature rich, configurable, self-contained and self-hosted paste bin web application. It is very easy to set up and use, and will only require a few megabytes of memory and disk storage. It takes only a couple minutes to set it up, why not give it a try now? [![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/szabodanika/microbin) - -Or install from Cargo: + +Or install from Cargo: `cargo install microbin` @@ -37,7 +37,7 @@ And run with your custom configuration: - Automatic dark mode (follows system preferences) - Very little CSS and absolutely no JS (see [water.css](https://github.com/kognise/water.css)) - Most of the above can be toggled on and off! - + ## 1 Usage ### What is a "pasta" anyway? @@ -222,7 +222,7 @@ server { listen 443 ssl; # managed by Certbot server_name microbin.myserver.com; - + location / { # Make sure to change the port if you are not running MicroBin at 8080! proxy_pass http://127.0.0.1:8080$request_uri; @@ -234,7 +234,7 @@ server { # Limit content size - I have 1GB because my MicroBin server is private, no one else will use it. client_max_body_size 1024M; - + ssl_certificate /etc/letsencrypt/live/microbin.myserver.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/microbin.myserver.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot @@ -329,3 +329,7 @@ Displays your MicroBin's version information. ### --wide Changes the maximum width of the UI from 720 pixels to 1080 pixels. + +### --no-file-upload + +Disables and hides the file upload option in the UI. \ No newline at end of file From c39b77823461dba7f47debc6fba885069cc3735b Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Sat, 1 Oct 2022 20:50:05 -0800 Subject: [PATCH 14/92] properly escape content --- src/pasta.rs | 4 ++++ templates/pasta.html | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pasta.rs b/src/pasta.rs index 3a54070..a728211 100644 --- a/src/pasta.rs +++ b/src/pasta.rs @@ -80,6 +80,10 @@ impl Pasta { pub fn content_not_highlighted(&self) -> String { html_highlight(&self.content, "txt") } + + pub fn content_escaped(&self) -> String { + self.content.replace("`", "\\`").replace("$", "\\$") + } } impl fmt::Display for Pasta { diff --git a/templates/pasta.html b/templates/pasta.html index adf52cb..587619c 100644 --- a/templates/pasta.html +++ b/templates/pasta.html @@ -33,7 +33,7 @@ @@ -79,8 +81,8 @@ code-line::before { background: transparent; top: 0; right: 0; - padding: 8px; - margin: 5px; + padding: 3px; + margin: 3px; } From e031ea0e9510bb3bd281d1c3b62fce7349aab3d4 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Sat, 22 Oct 2022 10:30:16 -0800 Subject: [PATCH 21/92] use a tag instead of button --- templates/pasta.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/templates/pasta.html b/templates/pasta.html index 1198e30..540011e 100644 --- a/templates/pasta.html +++ b/templates/pasta.html @@ -17,9 +17,9 @@
- +
{% if args.highlightsyntax %}
{{pasta.content_syntax_highlighted()}}
@@ -83,6 +83,7 @@ code-line::before { right: 0; padding: 3px; margin: 3px; + cursor: pointer; } From fd8a66bcbcc9c4d992d35d60705694e3be0dfb26 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Sat, 22 Oct 2022 10:34:39 -0800 Subject: [PATCH 22/92] use proper semantics for a tag as button --- templates/pasta.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/pasta.html b/templates/pasta.html index 540011e..388c8a6 100644 --- a/templates/pasta.html +++ b/templates/pasta.html @@ -17,7 +17,7 @@

- + Copy
From b1ccb43855080bc21bfec2f96daf8f5a44973271 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Sat, 22 Oct 2022 10:37:43 -0800 Subject: [PATCH 23/92] remove hash --- templates/pasta.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/pasta.html b/templates/pasta.html index 388c8a6..6e069ac 100644 --- a/templates/pasta.html +++ b/templates/pasta.html @@ -17,7 +17,7 @@

- + Copy
From 4980d72df278a2c4a15efdef8d3d482cffad7bf2 Mon Sep 17 00:00:00 2001 From: HeapUnderflow Date: Mon, 24 Oct 2022 12:55:09 +0200 Subject: [PATCH 24/92] Add example to README.MD --- README.MD | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/README.MD b/README.MD index 18006f6..b24f7a6 100644 --- a/README.MD +++ b/README.MD @@ -329,3 +329,61 @@ Displays your MicroBin's version information. ### --wide Changes the maximum width of the UI from 720 pixels to 1080 pixels. + +### --public-path [PUBLIC_PATH] + +Add the given public path prefix to all urls. + +This allows you to host MicroBin behind a reverse proxy on a subpath. +Note that MicroBin itself still expects all routes to be as without this option, and thus is unsuited +if you are running MicroBin directly. + +#### Example Usage (caddy) + +An example of running MicroBin behind the reverse proxy `caddy` on the path `/paste` (using systemd) + +**microbin.service** + +```unit file (systemd) +[Unit] +Description=Micobin Paste + +[Service] +Type=simple +User=microbin +# Path to your binary +ExecStart=/home/microbin/microbin/target/release/microbin +# Set your desired working directory, eg where microbin places its data +WorkingDirectory=/home/pi/bin/micro + +# bind to localhost, as its exposed via Caddy +Environment=MICROBIN_BIND=127.0.0.1 +# bind to a unused port +Environment=MICROBIN_PORT=31333 +# All your other config (change and add as needed) +Environment=MICROBIN_EDITABLE=true +Environment=MICROBIN_HIGHLIGHTSYNTAX=true +Environment=MICROBIN_THREADS=2 +Environment=MICROBIN_FOOTER_TEXT="Bin the bytes" +# Set your **public** url. Eg the one you will later use to access microbin +# Ensure it either starts with http(s):// or with a / +Environment=MICROBIN_PUBLIC_PATH="http://100.127.233.32/paste" + +[Install] +WantedBy=multi-user.target +``` + +**Caddyfile** + +```caddy +example.com { + # Your normal http root + root * /var/www/html + file_server + + # Route all requests to past + handle_path /paste/* { + reverse_proxy http://127.0.0.1:31333 + } +} +``` \ No newline at end of file From e258bcc2bd1bda7e39e2f7cda3b12d5627556471 Mon Sep 17 00:00:00 2001 From: Daniel Szabo Date: Tue, 25 Oct 2022 12:51:59 +0300 Subject: [PATCH 25/92] added missing bracket in args.rs --- src/args.rs | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/args.rs b/src/args.rs index e4029d4..b570cb8 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,9 +1,9 @@ +use clap::Parser; +use lazy_static::lazy_static; use std::convert::Infallible; use std::fmt; use std::net::IpAddr; use std::str::FromStr; -use clap::Parser; -use lazy_static::lazy_static; lazy_static! { pub static ref ARGS: Args = Args::parse(); @@ -12,61 +12,61 @@ lazy_static! { #[derive(Parser, Debug, Clone)] #[clap(author, version, about, long_about = None)] pub struct Args { - #[clap(long, env="MICROBIN_AUTH_USERNAME")] + #[clap(long, env = "MICROBIN_AUTH_USERNAME")] pub auth_username: Option, - #[clap(long, env="MICROBIN_AUTH_PASSWORD")] + #[clap(long, env = "MICROBIN_AUTH_PASSWORD")] pub auth_password: Option, - #[clap(long, env="MICROBIN_EDITABLE")] + #[clap(long, env = "MICROBIN_EDITABLE")] pub editable: bool, - #[clap(long, env="MICROBIN_FOOTER_TEXT")] + #[clap(long, env = "MICROBIN_FOOTER_TEXT")] pub footer_text: Option, - #[clap(long, env="MICROBIN_HIDE_FOOTER")] + #[clap(long, env = "MICROBIN_HIDE_FOOTER")] pub hide_footer: bool, - #[clap(long, env="MICROBIN_HIDE_HEADER")] + #[clap(long, env = "MICROBIN_HIDE_HEADER")] pub hide_header: bool, - #[clap(long, env="MICROBIN_HIDE_LOGO")] + #[clap(long, env = "MICROBIN_HIDE_LOGO")] pub hide_logo: bool, - #[clap(long, env="MICROBIN_NO_LISTING")] + #[clap(long, env = "MICROBIN_NO_LISTING")] pub no_listing: bool, - #[clap(long, env="MICROBIN_HIGHLIGHTSYNTAX")] + #[clap(long, env = "MICROBIN_HIGHLIGHTSYNTAX")] pub highlightsyntax: bool, - #[clap(short, long, env="MICROBIN_PORT", default_value_t = 8080)] + #[clap(short, long, env = "MICROBIN_PORT", default_value_t = 8080)] pub port: u16, #[clap(short, long, env="MICROBIN_BIND", default_value_t = IpAddr::from([0, 0, 0, 0]))] pub bind: IpAddr, - #[clap(long, env="MICROBIN_PRIVATE")] + #[clap(long, env = "MICROBIN_PRIVATE")] pub private: bool, - #[clap(long, env="MICROBIN_PURE_HTML")] + #[clap(long, env = "MICROBIN_PURE_HTML")] pub pure_html: bool, #[clap(long, env="MICROBIN_PUBLIC_PATH", default_value_t = PublicUrl(String::from("")))] pub public_path: PublicUrl, - #[clap(long, env="MICROBIN_READONLY")] + #[clap(long, env = "MICROBIN_READONLY")] pub readonly: bool, - #[clap(long, env="MICROBIN_TITLE")] + #[clap(long, env = "MICROBIN_TITLE")] pub title: Option, - #[clap(short, long, env="MICROBIN_THREADS", default_value_t = 1)] + #[clap(short, long, env = "MICROBIN_THREADS", default_value_t = 1)] pub threads: u8, - #[clap(long, env="MICROBIN_WIDE")] + #[clap(long, env = "MICROBIN_WIDE")] pub wide: bool, - - #[clap(short, long, env="MICROBIN_NO_FILE_UPLOAD")] + + #[clap(short, long, env = "MICROBIN_NO_FILE_UPLOAD")] pub no_file_upload: bool, } @@ -86,3 +86,4 @@ impl FromStr for PublicUrl { let uri = s.strip_suffix('/').unwrap_or(s).to_owned(); Ok(PublicUrl(uri)) } +} From d2e7234d96da812c496cf04f2079a55cc42e51c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Szab=C3=B3?= <25702868+szabodanika@users.noreply.github.com> Date: Thu, 27 Oct 2022 14:12:11 +0300 Subject: [PATCH 26/92] small ui improvements - fix width for pure html mode - improve copy button look and placement - make input field heights more consistent on pasta creation page --- Cargo.lock | 2060 +++++++++++++++++++++++++++++++++++++++++ templates/header.html | 71 +- templates/index.html | 31 +- templates/pasta.html | 91 +- 4 files changed, 2172 insertions(+), 81 deletions(-) create mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..5ad8089 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2060 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "actix-codec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-sink", + "log", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "actix-files" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d832782fac6ca7369a70c9ee9a20554623c5e51c76e190ad151780ebea1cf689" +dependencies = [ + "actix-http", + "actix-service", + "actix-utils", + "actix-web", + "askama_escape 0.10.3", + "bitflags", + "bytes", + "derive_more", + "futures-core", + "http-range", + "log", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", +] + +[[package]] +name = "actix-http" +version = "3.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c83abf9903e1f0ad9973cc4f7b9767fd5a03a583f51a5b7a339e07987cd2724" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "ahash", + "base64", + "bitflags", + "brotli", + "bytes", + "bytestring", + "derive_more", + "encoding_rs", + "flate2", + "futures-core", + "h2", + "http", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "mime", + "percent-encoding", + "pin-project-lite", + "rand", + "sha1", + "smallvec", + "tracing", + "zstd", +] + +[[package]] +name = "actix-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "actix-multipart" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9edfb0e7663d7fe18c8d5b668c9c1bcf79176b1dcc9d4da9592503209a6bfb0" +dependencies = [ + "actix-utils", + "actix-web", + "bytes", + "derive_more", + "futures-core", + "httparse", + "local-waker", + "log", + "mime", + "twoway", +] + +[[package]] +name = "actix-router" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" +dependencies = [ + "bytestring", + "http", + "regex", + "serde", + "tracing", +] + +[[package]] +name = "actix-rt" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000" +dependencies = [ + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio", + "num_cpus", + "socket2", + "tokio", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +dependencies = [ + "futures-core", + "paste", + "pin-project-lite", +] + +[[package]] +name = "actix-utils" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" +dependencies = [ + "local-waker", + "pin-project-lite", +] + +[[package]] +name = "actix-web" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d48f7b6534e06c7bfc72ee91db7917d4af6afe23e7d223b51e68fffbb21e96b9" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "actix-web-codegen", + "ahash", + "bytes", + "bytestring", + "cfg-if", + "cookie", + "derive_more", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "pin-project-lite", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2", + "time 0.3.16", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa9362663c8643d67b2d5eafba49e4cb2c8a053a29ed00a0bea121f17c76b13" +dependencies = [ + "actix-router", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "actix-web-httpauth" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c25a48b4684f90520183cd1a688e5f4f7e9905835fa75d02c0fe4f60fcdbe6" +dependencies = [ + "actix-service", + "actix-utils", + "actix-web", + "base64", + "futures-core", + "futures-util", + "pin-project-lite", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "askama" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d298738b6e47e1034e560e5afe63aa488fea34e25ec11b855a76f0d7b8e73134" +dependencies = [ + "askama_derive", + "askama_escape 0.10.3", + "askama_shared 0.11.2", +] + +[[package]] +name = "askama-filters" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ca4dc6a52fe9a1f3b62dd9c01c02102c73bff65c274d3c6bff1ccc850cfa83" +dependencies = [ + "askama_shared 0.9.1", + "chrono", + "regex", +] + +[[package]] +name = "askama_derive" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2925c4c290382f9d2fa3d1c1b6a63fa1427099721ecca4749b154cc9c25522" +dependencies = [ + "askama_shared 0.11.2", + "proc-macro2", + "syn", +] + +[[package]] +name = "askama_escape" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a577aeba5fec1aafb9f195d98cfcc38a78b588e4ebf9b15f62ca1c7aa33795a" + +[[package]] +name = "askama_escape" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" + +[[package]] +name = "askama_shared" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee517f4e33c27b129928e71d8a044d54c513e72e0b72ec5c4f5f1823e9de353" +dependencies = [ + "askama_escape 0.3.0", + "humansize", + "num-traits", + "serde", + "toml", +] + +[[package]] +name = "askama_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d6083ccb191711e9c2b80b22ee24a8381a18524444914c746d4239e21d1afaf" +dependencies = [ + "askama_escape 0.10.3", + "humansize", + "nom", + "num-traits", + "percent-encoding", + "proc-macro2", + "quote", + "serde", + "syn", + "toml", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "0.19.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "3.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "bytes" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" + +[[package]] +name = "bytesize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c58ec36aac5066d5ca17df51b3e70279f5670a72102f5752cb7e7c856adfc70" +dependencies = [ + "serde", +] + +[[package]] +name = "bytestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b6a75fd3048808ef06af5cd79712be8111960adaf89d90250974b38fc3928a" +dependencies = [ + "bytes", +] + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "time 0.1.44", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "clap" +version = "3.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "clap_lex", + "indexmap", + "once_cell", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917" +dependencies = [ + "percent-encoding", + "time 0.3.16", + "version_check", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cxx" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_logger" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "flate2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" + +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "h2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humansize" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "iana-time-zone" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "jobserver" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lexical-core" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" +dependencies = [ + "arrayvec", + "bitflags", + "cfg-if", + "ryu", + "static_assertions", +] + +[[package]] +name = "libc" +version = "0.2.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "line-wrap" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9" +dependencies = [ + "safemem", +] + +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linkify" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d9967eb7d0bc31c39c6f52e8fce42991c0cd1f7a2078326f0b7a399a584c8d" +dependencies = [ + "memchr", +] + +[[package]] +name = "local-channel" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" +dependencies = [ + "futures-core", + "futures-sink", + "futures-util", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "microbin" +version = "1.1.0" +dependencies = [ + "actix-files", + "actix-multipart", + "actix-web", + "actix-web-httpauth", + "askama", + "askama-filters", + "bytesize", + "chrono", + "clap", + "env_logger", + "futures", + "lazy_static", + "linkify", + "log", + "rand", + "sanitize-filename", + "serde", + "serde_json", + "syntect", +] + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", +] + +[[package]] +name = "nom" +version = "6.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" +dependencies = [ + "bitvec", + "funty", + "lexical-core", + "memchr", + "version_check", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "once_cell" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" + +[[package]] +name = "onig" +version = "6.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f" +dependencies = [ + "bitflags", + "libc", + "once_cell", + "onig_sys", +] + +[[package]] +name = "onig_sys" +version = "69.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "os_str_bytes" +version = "6.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "paste" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "plist" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd39bc6cdc9355ad1dc5eeedefee696bb35c34caf21768741e81826c0bbd7225" +dependencies = [ + "base64", + "indexmap", + "line-wrap", + "serde", + "time 0.3.16", + "xml-rs", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sanitize-filename" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf18934a12018228c5b55a6dae9df5d0641e3566b3630cb46cc55564068e7c2f" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] +name = "semver" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" + +[[package]] +name = "serde" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syntect" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c454c27d9d7d9a84c7803aaa3c50cd088d2906fe3c6e42da3209aa623576a8" +dependencies = [ + "bincode", + "bitflags", + "flate2", + "fnv", + "lazy_static", + "once_cell", + "onig", + "plist", + "regex-syntax", + "serde", + "serde_derive", + "serde_json", + "thiserror", + "walkdir", + "yaml-rust", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fab5c8b9980850e06d92ddbe3ab839c062c801f3927c0fb8abd6fc8e918fbca" +dependencies = [ + "itoa", + "libc", + "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bb801831d812c562ae7d2bfb531f26e66e4e1f6b17307ba4149c5064710e5b" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "winapi", +] + +[[package]] +name = "tokio-util" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "twoway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47" +dependencies = [ + "memchr", + "unchecked-index", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "unchecked-index" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.1+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b" +dependencies = [ + "cc", + "libc", +] diff --git a/templates/header.html b/templates/header.html index bb9c69a..351b3a4 100644 --- a/templates/header.html +++ b/templates/header.html @@ -1,8 +1,9 @@ + {% if args.title.as_ref().is_none() %} - MicroBin + MicroBin {%- else %} {{ args.title.as_ref().unwrap() }} {%- endif %} @@ -11,51 +12,53 @@ {% if !args.pure_html %} - + {%- endif %} - + {% if args.wide %} + -{%- else %} - -{%- endif %} -
- -{% if !args.hide_header %} - - - - {% if !args.hide_logo %} - μ - {%- endif %} - - {% if args.title.as_ref().is_none() %} - MicroBin {%- else %} - {{ args.title.as_ref().unwrap() }} - {%- endif %} - -New Pasta + + {%- endif %} +
-Pasta List + {% if !args.hide_header %} -Help + -
+ {% if !args.hide_logo %} + μ + {%- endif %} -{%- endif %} + {% if args.title.as_ref().is_none() %} + MicroBin + {%- else %} + {{ args.title.as_ref().unwrap() }} + {%- endif %} +
+ + New Pasta + + Pasta List + + Help + +
+ + {%- endif %} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 943de85..6d4ecdd 100644 --- a/templates/index.html +++ b/templates/index.html @@ -63,7 +63,9 @@

- +
+ +
{% endif %}
@@ -90,12 +92,33 @@
{% if args.readonly %} - + {%- else %} - + {%- endif %}
-{% include "footer.html" %} + + + +{% include "footer.html" %} \ No newline at end of file diff --git a/templates/pasta.html b/templates/pasta.html index 4238a57..d21e4fd 100644 --- a/templates/pasta.html +++ b/templates/pasta.html @@ -8,18 +8,20 @@ {%- endif %} {% if pasta.editable %} - Edit + Edit {%- endif %} - Remove + Remove
{{pasta.id_as_animals()}} +

- - Copy -
{% if args.highlightsyntax %}
{{pasta.content_syntax_highlighted()}}
@@ -44,48 +46,51 @@ -{% include "footer.html" %} +{% include "footer.html" %} \ No newline at end of file From 769901c895a65cdb504ad469af10db33d9cb0a4f Mon Sep 17 00:00:00 2001 From: Daniel Szabo Date: Thu, 27 Oct 2022 17:23:39 +0300 Subject: [PATCH 27/92] Added copy button for URL redirects Fixes #80 --- README.MD | 4 + templates/pastalist.html | 212 +++++++++++++++++++++------------------ 2 files changed, 118 insertions(+), 98 deletions(-) diff --git a/README.MD b/README.MD index 164ea11..fee6476 100644 --- a/README.MD +++ b/README.MD @@ -334,10 +334,14 @@ Changes the maximum width of the UI from 720 pixels to 1080 pixels. Add the given public path prefix to all urls. +The URL copy feature will only copy the entire URL if this is provided. Otherwise only the path (eg. `/url/dog-cat-bat`) will be copied to your clipboard! + This allows you to host MicroBin behind a reverse proxy on a subpath. Note that MicroBin itself still expects all routes to be as without this option, and thus is unsuited if you are running MicroBin directly. +Example: `--public-path https://myserver.com` or `--public-path http://localhost:8080` + #### Example Usage (caddy) An example of running MicroBin behind the reverse proxy `caddy` on the path `/paste` (using systemd) diff --git a/templates/pastalist.html b/templates/pastalist.html index c3d15a2..755cd60 100644 --- a/templates/pastalist.html +++ b/templates/pastalist.html @@ -11,105 +11,121 @@
{% if args.pure_html %} -{% else %} -
- {% endif %} - - - - - - - - -
Pastas
- Key - - Created - - Expiration - + {% else %} + + {% endif %} + + + + + + + + + - - - - {% for pasta in pastas %} - {% if pasta.pasta_type == "text" && !pasta.private %} - - - - - + + + {% for pasta in pastas %} + {% if pasta.pasta_type == "text" && !pasta.private %} + + + + + + {%- endif %} - {% if pasta.editable %} - Edit - {%- endif %} - Remove - - - {%- endif %} - {% endfor %} - -
Pastas
+ Key + + Created + + Expiration + -
- {{pasta.id_as_animals()}} - - {{pasta.created_as_string()}} - - {{pasta.expiration_as_string()}} - - Raw - {% if pasta.file.is_some() %} - File + +
+ {{pasta.id_as_animals()}} + + {{pasta.created_as_string()}} + + {{pasta.expiration_as_string()}} + + Raw + {% if pasta.file.is_some() %} + File + {%- endif %} + {% if pasta.editable %} + Edit + {%- endif %} + Remove +
-
-{% if args.pure_html %} - -{% else %} -
-{% endif %} - - - - - - - - -
URL Redirects
- Key - - Created - - Expiration - + {% endfor %} + +
+
+ {% if args.pure_html %} + + {% else %} +
+ {% endif %} + + + + + + + + + - - - {% for pasta in pastas %} - {% if pasta.pasta_type == "url" && !pasta.private %} - - - - - + + {% for pasta in pastas %} + {% if pasta.pasta_type == "url" && !pasta.private %} + + + + + + {%- endif %} - Remove - - - {%- endif %} - {% endfor %} - -
URL Redirects
+ Key + + Created + + Expiration + -
- {{pasta.id_as_animals()}} - - {{pasta.created_as_string()}} - - {{pasta.expiration_as_string()}} - - Raw - {% if pasta.editable %} - Edit + +
+ {{pasta.id_as_animals()}} + + {{pasta.created_as_string()}} + + {{pasta.expiration_as_string()}} + + Copy + {% if pasta.editable %} + Edit + {%- endif %} + Remove +
-
-{%- endif %} -{% include "footer.html" %} + {% endfor %} + +
+
+ {%- endif %} + + + + {% include "footer.html" %} \ No newline at end of file From 44b55ae08ebd298b1c21db1878cb7ba4cad63bf0 Mon Sep 17 00:00:00 2001 From: Daniel Szabo Date: Sat, 29 Oct 2022 14:11:55 +0300 Subject: [PATCH 28/92] Getting ready for 1.2.0 release: many smaller requests implemented - Implements #7 - Implements #42 and therefore #64 - Improved #53 - Implements #59 - Implements #61 - Implements #63 - Implements #80 - Implements #84 - Added Info page - Removed Help page - Bumped version number to 1.2.0 - Fixed a bug where wide mode was still 720px wide - Created FUNDING.yml - Reorganised arguments in README.MD and documented new options - Updated SECURITY.MD - Added display of last read time and read count - Increased default width to 800px to make UI less cluttered - Reorganised index page - New, better attach file button I want to spend some time testing these changes and let everyone have a look at them before tagging and releasing new artifacts. --- .github/workflows/FUNDING.yml | 4 + Cargo.lock | 334 +++++++++++++++++++++++++++++++++- Cargo.toml | 3 +- README.MD | 47 +++-- SECURITY.md | 13 +- src/args.rs | 21 +++ src/endpoints/create.rs | 42 ++++- src/endpoints/help.rs | 23 --- src/endpoints/info.rs | 42 +++++ src/endpoints/pasta.rs | 156 +++++++++++++--- src/endpoints/qr.rs | 34 ++++ src/main.rs | 18 +- src/pasta.rs | 56 ++++++ src/util/misc.rs | 18 +- templates/error.html | 4 +- templates/header.html | 14 +- templates/help.html | 160 ---------------- templates/index.html | 189 ++++++++++++++----- templates/info.html | 42 +++++ templates/pasta.html | 75 +++++--- templates/pastalist.html | 2 +- templates/qr.html | 7 + 22 files changed, 977 insertions(+), 327 deletions(-) create mode 100644 .github/workflows/FUNDING.yml delete mode 100644 src/endpoints/help.rs create mode 100644 src/endpoints/info.rs create mode 100644 src/endpoints/qr.rs delete mode 100644 templates/help.html create mode 100644 templates/info.html create mode 100644 templates/qr.html diff --git a/.github/workflows/FUNDING.yml b/.github/workflows/FUNDING.yml new file mode 100644 index 0000000..8fc887f --- /dev/null +++ b/.github/workflows/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: szabodanika +ko_fi: dani_sz diff --git a/Cargo.lock b/Cargo.lock index 5ad8089..21101c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,6 +401,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + [[package]] name = "bitflags" version = "1.3.2" @@ -455,6 +461,18 @@ version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +[[package]] +name = "bytemuck" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.2.1" @@ -558,6 +576,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "convert_case" version = "0.4.0" @@ -599,6 +623,55 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -676,6 +749,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + [[package]] name = "encoding_rs" version = "0.8.31" @@ -698,6 +777,21 @@ dependencies = [ "termcolor", ] +[[package]] +name = "exr" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide 0.6.2", + "smallvec", + "threadpool", +] + [[package]] name = "flate2" version = "1.0.24" @@ -705,7 +799,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.5.4", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", ] [[package]] @@ -835,8 +942,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", ] [[package]] @@ -858,6 +977,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554" +dependencies = [ + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -879,6 +1007,15 @@ dependencies = [ "libc", ] +[[package]] +name = "html-escape" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e7479fa1ef38eb49fb6a42c426be515df2d063f06cb8efd3e50af073dbc26c" +dependencies = [ + "utf8-width", +] + [[package]] name = "http" version = "0.2.8" @@ -954,6 +1091,25 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.24.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd8e4fb07cf672b1642304e731ef8a6a4c7891d67bb4fd4f5ce58cd6ed86803c" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + [[package]] name = "indexmap" version = "1.9.1" @@ -979,6 +1135,15 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" version = "0.3.60" @@ -1000,6 +1165,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "lexical-core" version = "0.7.6" @@ -1095,9 +1266,18 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "microbin" -version = "1.1.0" +version = "1.2.0" dependencies = [ "actix-files", "actix-multipart", @@ -1113,6 +1293,7 @@ dependencies = [ "lazy_static", "linkify", "log", + "qrcode-generator", "rand", "sanitize-filename", "serde", @@ -1145,6 +1326,15 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.5" @@ -1157,6 +1347,15 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + [[package]] name = "nom" version = "6.1.2" @@ -1180,6 +1379,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -1277,6 +1487,26 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1309,6 +1539,18 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "png" +version = "0.17.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0e7f4c94ec26ff209cee506314212639d6c91b80afb82984819fafce9df01c" +dependencies = [ + "bitflags", + "crc32fast", + "flate2", + "miniz_oxide 0.5.4", +] + [[package]] name = "ppv-lite86" version = "0.2.16" @@ -1348,6 +1590,23 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "qrcode-generator" +version = "4.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501c33c9127afb867693646b38817bf63a9a756d4b66aefbc5c0d7e5e8c3125a" +dependencies = [ + "html-escape", + "image", + "qrcodegen", +] + +[[package]] +name = "qrcodegen" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" + [[package]] name = "quote" version = "1.0.21" @@ -1393,6 +1652,30 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1459,6 +1742,12 @@ dependencies = [ "regex", ] +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + [[package]] name = "scopeguard" version = "1.1.0" @@ -1565,6 +1854,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -1652,6 +1950,26 @@ dependencies = [ "syn", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7259662e32d1e219321eb309d5f9d898b779769d81b76e762c07c8e5d38fcb65" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.1.44" @@ -1838,6 +2156,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8-width" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" + [[package]] name = "version_check" version = "0.9.4" @@ -1921,6 +2245,12 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 4b0821e..19a334a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "microbin" -version = "1.1.0" +version = "1.2.0" edition = "2021" authors = ["Daniel Szabo "] license = "BSD-3-Clause" @@ -31,6 +31,7 @@ env_logger = "0.9.0" actix-web-httpauth = "0.6.0" lazy_static = "1.4.0" syntect = "5.0" +qrcode-generator = "4.1.6" [profile.release] lto = true diff --git a/README.MD b/README.MD index fee6476..610cad0 100644 --- a/README.MD +++ b/README.MD @@ -255,6 +255,24 @@ Require username for HTTP Basic Authentication when visiting the service. If `-- Require password for HTTP Basic Authentication when visiting the service. Will not have any affect unless `--auth-username` is also set. If `--auth-username` is set but `--auth-password ` is not, just leave the password field empty when logging in. You can also just go to https://username:password@yourserver.net or https://username@yourserver.net if password is not set instead of typing into the password prompt. +### -b, --bind [ADDRESS] + +Default value: `0.0.0.0` + +Sets the bind address for the server will be listening on. Both ipv4 and ipv6 are supported. + +### --default-expiry [EXPIRY] + +Default value: `24hour` + +Selects the default expiry time in the dropdown list. + +Options: `1min`, `10min`, `1hour`, `24hour` and `1week` + +### --no-eternal-pasta + +Disables the option to create never expiring pastas. + ### --editable Enables editable pastas. You will still be able to make finalised pastas but there will be an extra checkbox to make your new pasta editable from the pasta list or the pasta view page. @@ -293,21 +311,26 @@ Default value: 8080 Sets the port for the server will be listening on. +### --public-path [PUBLIC_PATH] -### -b, --bind [ADDRESS] +Add the given public path prefix to all urls. -Default value: 0.0.0.0 +The URL copy feature will only copy the entire URL if this is provided. Otherwise only the path (eg. `/url/dog-cat-bat`) will be copied to your clipboard! -Sets the bind address for the server will be listening on. Both ipv4 and ipv6 are supported. +This allows you to host MicroBin behind a reverse proxy on a subpath. +Note that MicroBin itself still expects all routes to be as without this option, and thus is unsuited +if you are running MicroBin directly. -### --private - -Enables private pastas. Adds a new checkbox to make your pasta private, which then won't show up on the pastalist page. With the URL to your pasta, it will still be accessible. +Example: `--public-path https://myserver.com` or `--public-path http://localhost:8080` ### --pure-html Disables main CSS styling, just uses a few in-line stylings for the layout. With this option you will lose dark-mode support. +### --private + +Enables private pastas. Adds a new checkbox to make your pasta private, which then won't show up on the pastalist page. With the URL to your pasta, it will still be accessible. + ### --readonly Disables adding/editing/removing pastas entirely. @@ -330,18 +353,6 @@ Displays your MicroBin's version information. Changes the maximum width of the UI from 720 pixels to 1080 pixels. -### --public-path [PUBLIC_PATH] - -Add the given public path prefix to all urls. - -The URL copy feature will only copy the entire URL if this is provided. Otherwise only the path (eg. `/url/dog-cat-bat`) will be copied to your clipboard! - -This allows you to host MicroBin behind a reverse proxy on a subpath. -Note that MicroBin itself still expects all routes to be as without this option, and thus is unsuited -if you are running MicroBin directly. - -Example: `--public-path https://myserver.com` or `--public-path http://localhost:8080` - #### Example Usage (caddy) An example of running MicroBin behind the reverse proxy `caddy` on the path `/paste` (using systemd) diff --git a/SECURITY.md b/SECURITY.md index f86af39..695fc0f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,19 +1,12 @@ # Security Policy -## Supported Versions +## Version Support -Use this section to tell people about which versions of your project are -currently being supported with security updates. - -| Version | Supported | -| ------- | ------------------ | -| 1.1.* | :white_check_mark: | -| < 1.1.0 | :x: | +Currently we only have capacity to support the latest version of MicroBin. We recommend that you always update to the newest one and check our pages regularly for announcements. ## Reporting a Vulnerability -Security vulnerabilities can be reported directly to -the developer/maintainer at d@szab.eu. +Security vulnerabilities can be reported directly to the developer/maintainer at d@szab.eu. Sensitive information may be GPG encrypted with my public key available at https://szab.eu/assets/files/daniel-szabo-pub.asc. diff --git a/src/args.rs b/src/args.rs index b570cb8..3c61cbd 100644 --- a/src/args.rs +++ b/src/args.rs @@ -63,11 +63,32 @@ pub struct Args { #[clap(short, long, env = "MICROBIN_THREADS", default_value_t = 1)] pub threads: u8, + #[clap(short, long, env = "MICROBIN_GC_DAYS", default_value_t = 90)] + pub gc_days: u16, + + #[clap(long, env = "MICROBIN_ENABLE_BURN_AFTER")] + pub enable_burn_after: bool, + + #[clap(short, long, env = "MICROBIN_DEFAULT_BURN_AFTER", default_value_t = 0)] + pub default_burn_after: u16, + #[clap(long, env = "MICROBIN_WIDE")] pub wide: bool, + #[clap(long, env = "MICROBIN_QR")] + pub qr: bool, + + #[clap(long, env = "MICROBIN_NO_ETERNAL_PASTA")] + pub no_eternal_pasta: bool, + + #[clap(long, env = "MICROBIN_DEFAULT_EXPIRY", default_value = "24hour")] + pub default_expiry: String, + #[clap(short, long, env = "MICROBIN_NO_FILE_UPLOAD")] pub no_file_upload: bool, + + #[clap(long, env = "MICROBIN_CUSTOM_CSS")] + pub custom_css: Option, } #[derive(Debug, Clone)] diff --git a/src/endpoints/create.rs b/src/endpoints/create.rs index 7b6ca6d..30f463e 100644 --- a/src/endpoints/create.rs +++ b/src/endpoints/create.rs @@ -54,6 +54,9 @@ pub async fn create( private: false, editable: false, created: timenow, + read_count: 0, + burn_after_reads: 0, + last_read: timenow, pasta_type: String::from(""), expiration: 0, }; @@ -78,9 +81,34 @@ pub async fn create( "1hour" => timenow + 60 * 60, "24hour" => timenow + 60 * 60 * 24, "1week" => timenow + 60 * 60 * 24 * 7, - "never" => 0, + "never" => { + if ARGS.no_eternal_pasta { + timenow + 60 * 60 * 24 * 7 + } else { + 0 + } + } _ => { log::error!("{}", "Unexpected expiration time!"); + timenow + 60 * 60 * 24 * 7 + } + }; + } + + continue; + } + "burn_after" => { + while let Some(chunk) = field.try_next().await? { + new_pasta.burn_after_reads = match std::str::from_utf8(&chunk).unwrap() { + // give an extra read because the user will be redirected to the pasta page automatically + "1" => 2, + "10" => 10, + "100" => 100, + "1000" => 1000, + "10000" => 10000, + "0" => 0, + _ => { + log::error!("{}", "Unexpected burn after value!"); 0 } }; @@ -126,8 +154,11 @@ pub async fn create( } }; - std::fs::create_dir_all(format!("./pasta_data/public/{}", &new_pasta.id_as_animals())) - .unwrap(); + std::fs::create_dir_all(format!( + "./pasta_data/public/{}", + &new_pasta.id_as_animals() + )) + .unwrap(); let filepath = format!( "./pasta_data/public/{}/{}", @@ -158,6 +189,9 @@ pub async fn create( save_to_file(&pastas); Ok(HttpResponse::Found() - .append_header(("Location", format!("{}/pasta/{}", ARGS.public_path, to_animal_names(id)))) + .append_header(( + "Location", + format!("{}/pasta/{}", ARGS.public_path, to_animal_names(id)), + )) .finish()) } diff --git a/src/endpoints/help.rs b/src/endpoints/help.rs deleted file mode 100644 index 2ca8f38..0000000 --- a/src/endpoints/help.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::args::{Args, ARGS}; -use actix_web::{get, HttpResponse}; -use askama::Template; -use std::marker::PhantomData; - -#[derive(Template)] -#[template(path = "help.html")] -struct Help<'a> { - args: &'a Args, - _marker: PhantomData<&'a ()>, -} - -#[get("/help")] -pub async fn help() -> HttpResponse { - HttpResponse::Ok().content_type("text/html").body( - Help { - args: &ARGS, - _marker: Default::default(), - } - .render() - .unwrap(), - ) -} diff --git a/src/endpoints/info.rs b/src/endpoints/info.rs new file mode 100644 index 0000000..bbdc4fe --- /dev/null +++ b/src/endpoints/info.rs @@ -0,0 +1,42 @@ +use crate::args::{Args, ARGS}; +use crate::pasta::Pasta; +use crate::AppState; +use actix_web::{get, web, HttpResponse}; +use askama::Template; + +#[derive(Template)] +#[template(path = "info.html")] +struct Info<'a> { + args: &'a Args, + pastas: &'a Vec, + status: &'a String, + version_string: &'a String, + message: &'a String, +} + +#[get("/info")] +pub async fn info(data: web::Data) -> HttpResponse { + // get access to the pasta collection + let mut pastas = data.pastas.lock().unwrap(); + + // todo status report more sophisticated + let mut status = "OK"; + let mut message = ""; + + if ARGS.public_path.to_string() == "" { + status = "WARNING"; + message = "Warning: No public URL set with --public-path parameter. QR code and URL Copying functions have been disabled" + } + + HttpResponse::Ok().content_type("text/html").body( + Info { + args: &ARGS, + pastas: &pastas, + status: &String::from(status), + version_string: &String::from("1.2.0-20221029"), + message: &String::from(message), + } + .render() + .unwrap(), + ) +} diff --git a/src/endpoints/pasta.rs b/src/endpoints/pasta.rs index 26ac11d..4242ab7 100644 --- a/src/endpoints/pasta.rs +++ b/src/endpoints/pasta.rs @@ -1,12 +1,14 @@ -use actix_web::{get, web, HttpResponse}; -use askama::Template; - use crate::args::{Args, ARGS}; +use crate::dbio::save_to_file; use crate::endpoints::errors::ErrorTemplate; use crate::pasta::Pasta; use crate::util::animalnumbers::to_u64; use crate::util::misc::remove_expired; use crate::AppState; +use actix_web::rt::time; +use actix_web::{get, web, HttpResponse}; +use askama::Template; +use std::time::{SystemTime, UNIX_EPOCH}; #[derive(Template)] #[template(path = "pasta.html", escape = "none")] @@ -17,27 +19,60 @@ struct PastaTemplate<'a> { #[get("/pasta/{id}")] pub async fn getpasta(data: web::Data, id: web::Path) -> HttpResponse { + // get access to the pasta collection let mut pastas = data.pastas.lock().unwrap(); + // get the u64 id from the animal names in the path let id = to_u64(&*id.into_inner()).unwrap_or(0); - println!("{}", id); - + // remove expired pastas (including this one if needed) remove_expired(&mut pastas); - for pasta in pastas.iter() { + // find the index of the pasta in the collection based on u64 id + let mut index: usize = 0; + let mut found: bool = false; + for (i, pasta) in pastas.iter().enumerate() { if pasta.id == id { - return HttpResponse::Ok().content_type("text/html").body( - PastaTemplate { - pasta: &pasta, - args: &ARGS, - } - .render() - .unwrap(), - ); + index = i; + found = true; + break; } } + if found { + // increment read count + pastas[index].read_count = pastas[index].read_count + 1; + + // save the updated read count + save_to_file(&pastas); + + // serve pasta in template + let response = HttpResponse::Ok().content_type("text/html").body( + PastaTemplate { + pasta: &pastas[index], + args: &ARGS, + } + .render() + .unwrap(), + ); + + // get current unix time in seconds + let timenow: i64 = match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(n) => n.as_secs(), + Err(_) => { + log::error!("SystemTime before UNIX EPOCH!"); + 0 + } + } as i64; + + // update last read time + pastas[index].last_read = timenow; + + return response; + } + + // otherwise + // send pasta not found error HttpResponse::Ok() .content_type("text/html") .body(ErrorTemplate { args: &ARGS }.render().unwrap()) @@ -45,26 +80,62 @@ pub async fn getpasta(data: web::Data, id: web::Path) -> HttpR #[get("/url/{id}")] pub async fn redirecturl(data: web::Data, id: web::Path) -> HttpResponse { + // get access to the pasta collection let mut pastas = data.pastas.lock().unwrap(); + // get the u64 id from the animal names in the path let id = to_u64(&*id.into_inner()).unwrap_or(0); + // remove expired pastas (including this one if needed) remove_expired(&mut pastas); - for pasta in pastas.iter() { + // find the index of the pasta in the collection based on u64 id + let mut index: usize = 0; + let mut found: bool = false; + for (i, pasta) in pastas.iter().enumerate() { if pasta.id == id { - if pasta.pasta_type == "url" { - return HttpResponse::Found() - .append_header(("Location", String::from(&pasta.content))) - .finish(); - } else { - return HttpResponse::Ok() - .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()); - } + index = i; + found = true; + break; } } + if found { + // increment read count + pastas[index].read_count = pastas[index].read_count + 1; + + // save the updated read count + save_to_file(&pastas); + + // send redirect if it's a url pasta + if pastas[index].pasta_type == "url" { + let response = HttpResponse::Found() + .append_header(("Location", String::from(&pastas[index].content))) + .finish(); + + // get current unix time in seconds + let timenow: i64 = match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(n) => n.as_secs(), + Err(_) => { + log::error!("SystemTime before UNIX EPOCH!"); + 0 + } + } as i64; + + // update last read time + pastas[index].last_read = timenow; + + return response; + // send error if we're trying to open a non-url pasta as a redirect + } else { + HttpResponse::Ok() + .content_type("text/html") + .body(ErrorTemplate { args: &ARGS }.render().unwrap()); + } + } + + // otherwise + // send pasta not found error HttpResponse::Ok() .content_type("text/html") .body(ErrorTemplate { args: &ARGS }.render().unwrap()) @@ -72,17 +143,50 @@ pub async fn redirecturl(data: web::Data, id: web::Path) -> Ht #[get("/raw/{id}")] pub async fn getrawpasta(data: web::Data, id: web::Path) -> String { + // get access to the pasta collection let mut pastas = data.pastas.lock().unwrap(); + // get the u64 id from the animal names in the path let id = to_u64(&*id.into_inner()).unwrap_or(0); + // remove expired pastas (including this one if needed) remove_expired(&mut pastas); - for pasta in pastas.iter() { + // find the index of the pasta in the collection based on u64 id + let mut index: usize = 0; + let mut found: bool = false; + for (i, pasta) in pastas.iter().enumerate() { if pasta.id == id { - return pasta.content.to_owned(); + index = i; + found = true; + break; } } + if found { + // increment read count + pastas[index].read_count = pastas[index].read_count + 1; + + // get current unix time in seconds + let timenow: i64 = match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(n) => n.as_secs(), + Err(_) => { + log::error!("SystemTime before UNIX EPOCH!"); + 0 + } + } as i64; + + // update last read time + pastas[index].last_read = timenow; + + // save the updated read count + save_to_file(&pastas); + + // send raw content of pasta + return pastas[index].content.to_owned(); + } + + // otherwise + // send pasta not found error as raw text String::from("Pasta not found! :-(") } diff --git a/src/endpoints/qr.rs b/src/endpoints/qr.rs new file mode 100644 index 0000000..4d714d5 --- /dev/null +++ b/src/endpoints/qr.rs @@ -0,0 +1,34 @@ +use crate::args::{Args, ARGS}; +use crate::pasta::Pasta; +use crate::util::misc::{self, remove_expired}; +use crate::AppState; +use actix_web::{get, web, HttpResponse}; +use askama::Template; +use qrcode_generator::QrCodeEcc; +use std::time::{SystemTime, UNIX_EPOCH}; + +#[derive(Template)] +#[template(path = "qr.html", escape = "none")] +struct QRTemplate<'a> { + qr: &'a String, + args: &'a Args, +} + +#[get("/qr/{id}")] +pub async fn getqr(data: web::Data, id: web::Path) -> HttpResponse { + // find the index of the pasta in the collection based on u64 id + + let svg: String = misc::string_to_qr_svg( + format!("{}/pasta/{}", &ARGS.public_path, &*id.into_inner()).as_str(), + ); + + // serve qr code in template + HttpResponse::Ok().content_type("text/html").body( + QRTemplate { + qr: &svg, + args: &ARGS, + } + .render() + .unwrap(), + ) +} diff --git a/src/main.rs b/src/main.rs index 099a2a6..86e9322 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ extern crate core; use crate::args::ARGS; use crate::endpoints::{ - create, edit, errors, help, pasta as pasta_endpoint, pastalist, remove, static_resources, + create, edit, errors, info, pasta as pasta_endpoint, pastalist, qr, remove, static_resources, }; use crate::pasta::Pasta; use crate::util::dbio; @@ -31,9 +31,10 @@ pub mod endpoints { pub mod create; pub mod edit; pub mod errors; - pub mod help; + pub mod info; pub mod pasta; pub mod pastalist; + pub mod qr; pub mod remove; pub mod static_resources; } @@ -66,8 +67,14 @@ async fn main() -> std::io::Result<()> { match fs::create_dir_all("./pasta_data/public") { Ok(dir) => dir, Err(error) => { - log::error!("Couldn't create data directory ./pasta_data/public/: {:?}", error); - panic!("Couldn't create data directory ./pasta_data/public/: {:?}", error); + log::error!( + "Couldn't create data directory ./pasta_data/public/: {:?}", + error + ); + panic!( + "Couldn't create data directory ./pasta_data/public/: {:?}", + error + ); } }; @@ -80,13 +87,14 @@ async fn main() -> std::io::Result<()> { .app_data(data.clone()) .wrap(middleware::NormalizePath::trim()) .service(create::index) - .service(help::help) + .service(info::info) .service(pasta_endpoint::getpasta) .service(pasta_endpoint::getrawpasta) .service(pasta_endpoint::redirecturl) .service(edit::get_edit) .service(edit::post_edit) .service(static_resources::static_resources) + .service(qr::getqr) .service(actix_files::Files::new("/file", "./pasta_data/public/")) .service(web::resource("/upload").route(web::post().to(create::create))) .default_service(web::route().to(errors::not_found)) diff --git a/src/pasta.rs b/src/pasta.rs index a728211..b6e98bd 100644 --- a/src/pasta.rs +++ b/src/pasta.rs @@ -3,6 +3,7 @@ use chrono::{Datelike, Local, TimeZone, Timelike}; use serde::{Deserialize, Serialize}; use std::fmt; use std::path::Path; +use std::time::{SystemTime, UNIX_EPOCH}; use crate::util::animalnumbers::to_animal_names; use crate::util::syntaxhighlighter::html_highlight; @@ -39,6 +40,9 @@ pub struct Pasta { pub editable: bool, pub created: i64, pub expiration: i64, + pub last_read: i64, + pub read_count: u64, + pub burn_after_reads: u64, pub pasta_type: String, } @@ -73,6 +77,58 @@ impl Pasta { } } + pub fn last_read_time_ago_as_string(&self) -> String { + // get current unix time in seconds + let timenow: i64 = match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(n) => n.as_secs(), + Err(_) => { + log::error!("SystemTime before UNIX EPOCH!"); + 0 + } + } as i64; + + // get seconds since last read and convert it to days + let days = ((timenow - self.last_read) / 86400) as u16; + if days > 1 { + return format!("{} days ago", days); + }; + + // it's less than 1 day, let's do hours then + let hours = ((timenow - self.last_read) / 3600) as u16; + if hours > 1 { + return format!("{} hours ago", hours); + }; + + // it's less than 1 hour, let's do minutes then + let minutes = ((timenow - self.last_read) / 60) as u16; + if minutes > 1 { + return format!("{} minutes ago", minutes); + }; + + // it's less than 1 minute, let's do seconds then + let seconds = (timenow - self.last_read) as u16; + if seconds > 1 { + return format!("{} seconds ago", seconds); + }; + + // it's less than 1 second????? + return String::from("just now"); + } + + pub fn last_read_days_ago(&self) -> u16 { + // get current unix time in seconds + let timenow: i64 = match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(n) => n.as_secs(), + Err(_) => { + log::error!("SystemTime before UNIX EPOCH!"); + 0 + } + } as i64; + + // get seconds since last read and convert it to days + return ((timenow - self.last_read) / 86400) as u16; + } + pub fn content_syntax_highlighted(&self) -> String { html_highlight(&self.content, &self.extension) } diff --git a/src/util/misc.rs b/src/util/misc.rs index d1f4693..489b891 100644 --- a/src/util/misc.rs +++ b/src/util/misc.rs @@ -1,6 +1,8 @@ use std::time::{SystemTime, UNIX_EPOCH}; +use crate::args::ARGS; use linkify::{LinkFinder, LinkKind}; +use qrcode_generator::QrCodeEcc; use std::fs; use crate::{dbio, Pasta}; @@ -16,8 +18,16 @@ pub fn remove_expired(pastas: &mut Vec) { } as i64; pastas.retain(|p| { - // expiration is `never` or not reached - if p.expiration == 0 || p.expiration > timenow { + // keep if: + // expiration is `never` or not reached + // AND + // read count is less than burn limit, or no limit set + // AND + // has been read in the last N days where N is the arg --gc-days OR N is 0 (no GC) + if (p.expiration == 0 || p.expiration > timenow) + && (p.read_count < p.burn_after_reads || p.burn_after_reads == 0) + && (p.last_read_days_ago() < ARGS.gc_days || ARGS.gc_days == 0) + { // keep true } else { @@ -45,6 +55,10 @@ pub fn remove_expired(pastas: &mut Vec) { dbio::save_to_file(pastas); } +pub fn string_to_qr_svg(str: &str) -> String { + qrcode_generator::to_svg_to_string(str, QrCodeEcc::Low, 512, None::<&str>).unwrap() +} + pub fn is_valid_url(url: &str) -> bool { let finder = LinkFinder::new(); let spans: Vec<_> = finder.spans(url).collect(); diff --git a/templates/error.html b/templates/error.html index 6e60b7c..806229e 100644 --- a/templates/error.html +++ b/templates/error.html @@ -4,7 +4,7 @@ Not Found

- Go Home + Go Home

-{% include "footer.html" %} +{% include "footer.html" %} \ No newline at end of file diff --git a/templates/header.html b/templates/header.html index 351b3a4..d282c93 100644 --- a/templates/header.html +++ b/templates/header.html @@ -12,13 +12,18 @@ {% if !args.pure_html %} + {% if args.custom_css.as_ref().is_none() %} + {%- else %} + {%- endif %} + {%- endif %} + {% if args.wide %} - New Pasta + New + Pasta Pasta List - Help + Info
diff --git a/templates/help.html b/templates/help.html deleted file mode 100644 index abef0ce..0000000 --- a/templates/help.html +++ /dev/null @@ -1,160 +0,0 @@ -{% include "header.html" %} - - -

Welcome to MicroBin!

-

This page contains help regarding the installation, configuration and use of MicroBin. If you have questions that are not answered here, head to our GitHub repository.

-

1 Usage

-

What is a "pasta" anyway?

-

In microbin, a pasta can be:

-
    -
  • A text that you want to paste from one machine to another, eg. some code
  • -
  • A file that you want to share, eg. a video that is too large for Discord, a zip with a code project in it or an image
  • -
  • A URL redirect
  • -
-

When is MicroBin useful?

-

You can use MicroBin

-
    -
  • As a URL shortener/redirect service,
  • -
  • To send long texts to other people,
  • -
  • To send large files to other people,
  • -
  • To serve content on the web, eg. configuration files for testing, images, or any other file content using the Raw functionality,
  • -
  • To move files between your desktop and a server you access from the console,
  • -
  • As a "postbox" service where people can upload their files or texts, but they cannot see or remove what others sent you - just disable the pastalist page
  • -
  • To take notes! Simply create an editable pasta.
  • -
-

...and many other things, why not get creative?

-

Creating a Pasta

-

Navigate to the root of your server, for example https://microbin.myserver.com/. This should show you a form where you will at the very least see an expiration selector, a file attachment input, a content text field and a green save button. Depending on your configuration there miight also be a syntax highlight selector, an editable checkbox and a private ceckbox.

-

Use the expiration dropdown to choose how long you want your pasta to exist. When the selected time has expired, it will be removed from the server. The content can be any text, including plain text, code, html, even a URL. A URL is a special case, because when you open the pasta again, it will redirect you to that URL instead of showing it as a text. Entering content is optional, and so is the file attachment. If you want, you can even submit a pasta completely empty.

-

You will be redirected to the URL of the pasta, which will end with a few animal names. If you remember those animals, you can simply type them in on another machine and open your pasta elsewhere.

-

If you have editable pastas enabled and you check the editable checkbox, then later on there will be an option to change the text content of your pasta. Selecting the private checkbox will simply prevent your pasta to show up on the pasta list page, if that is enabled.

-

If you have syntax higlighting enabled, then select your language from the dropdown, or leave it as none if you just want to upload plain with no highlighting.

-

Listing Pastas

-

If you have pasta listing enabled, then there is a pasta list option in the navigation bar, which will list all the pastas on the server in two groups: regular pastas and URL redirects (pastas containing nothing but a URL). If you have private pastas enabled, they will not show up here at all.

-

From the pasta list page, you will be able to view individual pastas by clicking on their animal identifiers on the lest, view their raw contrent by clicking on the Raw button, remove them, and if you have editable pastas enabled, then open them in edit view.

-

Use MicroBin from the console with cURL

-

Simple text Pasta: curl -d "expiration=10min&content=This is a test pasta" -X POST https://microbin.myserver.com/create

-

File contents: curl -d "expiration=10min&content=$( < mypastafile.txt )" -X POST https://microbin.myserver.com/create

-

Available expiration options: - 1min, 10min, 1hour, 24hour, 1week, never

-

Use cURL to read the pasta: curl https://microbin.myserver.com/rawpasta/fish-pony-crow,

-

or to download the pasta: curl https://microbin.myserver.com/rawpasta/fish-pony-crow > output.txt (use /file instead of /rawpasta to download attached file).

-

2 Installation

-

From Cargo

-

Install from Cargo:

-

cargo install microbin

-

Remember, MicroBin will create your database and file storage wherever you execute it. I recommend that you create a folder for it first and execute it there:

-

mkdir ~/microbin/

-

cd ~/microbin/

-

microbin --port 8080 --highlightsyntax --editable

-

Building MicroBin

-

Simply clone the repository, build it with cargo build --release and run the microbin executable in the created target/release/ directory. It will start on port 8080. You can change the port with -p or --port CL arguments. For other arguments see the Wiki.

-
git clone https://github.com/szabodanika/microbin.git
-cd microbin
-cargo build --release
-./target/release/microbin -p 80
-

MicroBin as a service

-

To install it as a service on your Linux machine, create a file called /etc/systemd/system/microbin.service, paste this into it with the [username] and [path to installation directory] replaced with the actual values. If you installed MicroBin from Cargo, your executable will be in your system's Cargo directory, e.g. /Users/daniel/.cargo/bin/microbin.

-
[Unit]
-Description=MicroBin
-After=network.target
-
-[Service]
-Type=simple
-Restart=always
-User=[username]
-RootDirectory=/
-WorkingDirectory=[path to installation directory]
-ExecStart=[path to installation directory]/target/release/microbin
-
-[Install]
-WantedBy=multi-user.target
-

Here is my microbin.service for example, with some optional arguments:

-
[Unit]
-Description=MicroBin
-After=network.target
-
-[Service]
-Type=simple
-Restart=always
-User=ubuntu
-RootDirectory=/
-
-# This is the directory where I want to run microbin. It will store all the pastas here.
-WorkingDirectory=/home/ubuntu/server/microbin
-
-# This is the location of my executable - I also have 2 optional features enabled
-ExecStart=/home/ubuntu/server/microbin/target/release/microbin --editable --linenumbers --highlightsyntax
-
-# I keep my installation in the home directory, so I need to add this
-ProtectHome=off
-
-[Install]
-WantedBy=multi-user.target
-

Then start the service with systemctl start microbin and enable it on boot with systemctl enable microbin. To update your MicroBin, simply update or clone the repository again, build it again, and then restart the service with systemctl restart microbin. An update will never affect your existing pastas, unless there is a breaking change in the data model (in which case MicroBin just won't be able to import your DB), which will always be mentioned explicitly.

-

NGINX configuration

-
server {
-    # I have HTTPS enabled using certbot - you can use HTTP of course if you want!
-  listen 443 ssl; # managed by Certbot
-
-    server_name    microbin.myserver.com;
-
-    location / {
-            # Make sure to change the port if you are not running MicroBin at 8080!
-        proxy_pass            http://127.0.0.1:8080$request_uri;
-        proxy_set_header    Host $host;
-        proxy_set_header    X-Forwarded-Proto $scheme;
-        proxy_set_header    X-Real-IP $remote_addr;
-        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
-    }
-
-    # Limit content size - I have 1GB because my MicroBin server is private, no one else will use it.
-    client_max_body_size 1024M;
-
-  ssl_certificate /etc/letsencrypt/live/microbin.myserver.com/fullchain.pem; # managed by Certbot
-  ssl_certificate_key /etc/letsencrypt/live/microbin.myserver.com/privkey.pem; # managed by Certbot
-  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
-  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
-}
-

3 Command Line Arguments

-

There is an ever expanding list of customisations built into MicroBin so you can use it the way you want. Instead of a configuration file, we simply use arguments that you pass to the executable, making the workflow even simpler. Read the following options and if you cannot find what you need, you can always open an issue at our GitHub repository and request a new feature!

-

--auth-username [AUTH_USERNAME]

-

Require username for HTTP Basic Authentication when visiting the service. If --auth-username is set but --auth-password is not, just leave the password field empty when logging in. You can also just go to https://username:password@yourserver.net or https://username@yourserver.net if password is not set instead of typing into the password

-

--auth-password [AUTH_PASSWORD]

-

Require password for HTTP Basic Authentication when visiting the service. Will not have any affect unless --auth-username is also set. If --auth-username is set but --auth-password is not, just leave the password field empty when logging in. You can also just go to https://username:password@yourserver.net or https://username@yourserver.net if password is not set instead of typing into the password prompt.

-

--editable

-

Enables editable pastas. You will still be able to make finalised pastas but there will be an extra checkbox to make your new pasta editable from the pasta list or the pasta view page.

- -

Replaces the default footer text with your own. If you want to hide the footer, use --hide-footer instead.

-

-h, --help

-

Show all commands in the terminal.

- -

Hides the footer on every page.

-

--hide-header

-

Hides the navigation bar on every page.

- -

Hides the MicroBin logo from the navigation bar on every page.

-

--no-listing

-

Disables the /pastalist endpoint, essentially making all pastas private.

-

--highlightsyntax

-

Enables syntax highlighting support. When creating a new pasta, a new dropdown selector will be added where you can select your pasta's syntax, or just leave it empty for no highlighting.

-

-p, --port [PORT]

-

Default value: 8080

-

Sets the port for the server will be listening on.

-

--private

-

Enables private pastas. Adds a new checkbox to make your pasta private, which then won't show up on the pastalist page. With the URL to your pasta, it will still be accessible.

-

--pure-html

-

Disables main CSS styling, just uses a few in-line stylings for the layout. With this option you will lose dark-mode support.

-

--readonly

-

Disables adding/editing/removing pastas entirely.

-

--title [TITLE]

-

Replaces "MicroBin" with your title of choice in the navigation bar.

-

-t, --threads [THREADS]

-

Default value: 1

-

Number of workers MicroBin is allowed to have. Increase this to the number of CPU cores you have if you want to go beast mode, but for personal use one worker is enough.

-

-V, --version

-

Displays your MicroBin's version information.

-

--wide

-

Changes the maximum width of the UI from 720 pixels to 1080 pixels.

- -{% include "footer.html" %} diff --git a/templates/index.html b/templates/index.html index 6d4ecdd..3c92851 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,26 +1,108 @@ {% include "header.html" %} +

-
+

+ {% if args.enable_burn_after %} +
+
+ +
+ {%- endif %} + {% if args.highlightsyntax %}
-
+
{%- endif %} - {% if !args.no_file_upload %}
- -
-
- + {% if args.editable || args.private %} + + {%- endif %} + {% if args.editable %} +
+ +
+ {%- endif %} + {% if args.private %} +
+ + +
+ {%- endif %}
- {% endif %} + + + +

-
-
- {% if args.editable %} -
- - -
- {%- endif %} - {% if args.private %} -
- - -
- {%- endif %} + {% if !args.no_file_upload %} +
+ +
+
- + {% endif %} {% if args.readonly %} {%- else %} @@ -101,23 +183,40 @@
+ + diff --git a/templates/info.html b/templates/info.html new file mode 100644 index 0000000..2e12c73 --- /dev/null +++ b/templates/info.html @@ -0,0 +1,42 @@ +{% include "header.html" %} + +

Welcome to MicroBin

+
+ + +
+

Info

+ + + + + + + + + + + + + +
Version{{version_string}}
Status{{status}}
Pastas{{pastas.len()}}
+
+
+ +{% if message != "" %} +

Messages

+

{{message}}

+{%- endif %} + +
+ +{% include "footer.html" %} \ No newline at end of file diff --git a/templates/pasta.html b/templates/pasta.html index d21e4fd..decfb75 100644 --- a/templates/pasta.html +++ b/templates/pasta.html @@ -1,26 +1,39 @@ {% include "header.html" %}
- Raw Text Content - {% if pasta.file.is_some() %} - - Attached file'{{pasta.file.as_ref().unwrap().name()}}' [{{pasta.file.as_ref().unwrap().size}}] - + {% if pasta.content != "No Text Content" %} + + Raw Text + Content + {%- endif %} + {% if args.qr && args.public_path.to_string() != "" %} + QR {%- endif %} {% if pasta.editable %} - Edit + Edit {%- endif %} - Remove + Remove
- {{pasta.id_as_animals()}} - + {%- endif %}
+{% if pasta.file.is_some() %}
+
+ + Download attached file: '{{pasta.file.as_ref().unwrap().name()}}' [{{pasta.file.as_ref().unwrap().size}}] + +{%- endif %} +
+
+{% if pasta.content != "No Text Content" %}
{% if args.highlightsyntax %} @@ -30,16 +43,33 @@ {%- endif %}
+{%- endif %} +
+

Read {{pasta.read_count}} times, last {{pasta.last_read_time_ago_as_string()}}

+
+ +
+ + {% include "footer.html" %} \ No newline at end of file From edd46eae58eae1c5a81d626e43c32387a541bceb Mon Sep 17 00:00:00 2001 From: Daniel Szabo Date: Mon, 7 Nov 2022 20:30:33 +0200 Subject: [PATCH 40/92] Improved /pasta and /pastalist UX - adjusted table column widths so buttons dont wrap into next row - added Open button to url pastas so clicking on their keys redirect to their /pasta view, consistent with the rest of the pastas - added copy redirect button to /pasta view of url pastas to make it easier to get the /url endpoint url --- templates/pasta.html | 28 ++++++++++++++---- templates/pastalist.html | 64 +++++++++++++++++----------------------- 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/templates/pasta.html b/templates/pasta.html index 47dd01d..360425c 100644 --- a/templates/pasta.html +++ b/templates/pasta.html @@ -1,9 +1,14 @@ {% include "header.html" %}
{% if pasta.content != "No Text Content" %} - + {% if args.public_path.to_string() != "" && pasta.pasta_type == "url" %} + + {%- endif %} Raw Text Content {%- endif %} @@ -19,7 +24,7 @@ {{pasta.id_as_animals()}} {% if args.public_path.to_string() != "" %} - {%- endif %} @@ -59,8 +64,10 @@ - {% include "footer.html" %} \ No newline at end of file + {% include "footer.html" %} From d1c583d4b03e19da22c9871630c4f5f36091b754 Mon Sep 17 00:00:00 2001 From: Jade Date: Sat, 4 Mar 2023 01:10:16 +0100 Subject: [PATCH 71/92] ideas --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2729eb3..1daedc8 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Please do not ask for help in the issues of the original MicroBin repository, I' - [ ] Markdown pastas - [ ] further endpoint configuration - [x] customizable `pasta`, `url` and `raw` endpoints + - [ ] simplified media embed endpoints (/file/$id or /embed/$id by default? maybe with compression?) - [ ] disable remove - [x] Click logo/name to get to root - [ ] switch to other template engine From e4575d7d6e720a601888e236450a0c1d4d443822 Mon Sep 17 00:00:00 2001 From: Jade Date: Sun, 5 Mar 2023 15:21:12 +0100 Subject: [PATCH 72/92] rebrand + added dockerfile agian --- Cargo.lock | 58 ++-- Cargo.toml | 6 +- Dockerfile | 37 +++ src/args.rs | 64 ++-- templates/assets/favicon.svg | 84 ++++- templates/assets/logo.png | Bin 4402 -> 3133 bytes templates/assets/logo.svg | 81 +++++ templates/assets/water.css | 627 ++++++++++++++++++++++++++++++++++- templates/footer.html | 2 +- templates/header.html | 14 +- templates/index.html | 9 +- 11 files changed, 901 insertions(+), 81 deletions(-) create mode 100644 Dockerfile create mode 100644 templates/assets/logo.svg diff --git a/Cargo.lock b/Cargo.lock index 9479b4a..db1ad9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1159,6 +1159,35 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "karton" +version = "2.0.0" +dependencies = [ + "actix-files", + "actix-multipart", + "actix-web", + "actix-web-httpauth", + "askama", + "askama-filters", + "bytesize", + "chrono", + "clap", + "env_logger", + "futures", + "harsh", + "lazy_static", + "linkify", + "log", + "mime_guess", + "qrcode-generator", + "rand", + "rust-embed", + "sanitize-filename", + "serde", + "serde_json", + "syntect", +] + [[package]] name = "language-tags" version = "0.3.2" @@ -1281,35 +1310,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "microbin" -version = "2.0.0" -dependencies = [ - "actix-files", - "actix-multipart", - "actix-web", - "actix-web-httpauth", - "askama", - "askama-filters", - "bytesize", - "chrono", - "clap", - "env_logger", - "futures", - "harsh", - "lazy_static", - "linkify", - "log", - "mime_guess", - "qrcode-generator", - "rand", - "rust-embed", - "sanitize-filename", - "serde", - "serde_json", - "syntect", -] - [[package]] name = "mime" version = "0.3.16" diff --git a/Cargo.toml b/Cargo.toml index b1db321..56898cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,14 @@ [package] -name = "microbin" +name = "karton" version = "2.0.0" edition = "2021" -authors = ["Daniel Szabo ", "Jade "] +authors = ["Jade ", "Daniel Szabo "] license = "BSD-3-Clause" description = "Simple, performant, configurable, entirely self-contained Pastebin and URL shortener." readme = "README.md" homepage = "https://gitlab.com/obsidianical/microbin" repository = "https://gitlab.com/obsidianical/microbin" -keywords = ["pastebin", "pastabin", "microbin", "actix", "selfhosted"] +keywords = ["pastebin", "pastabin", "karton", "microbin", "actix", "selfhosted"] categories = ["pastebins"] [dependencies] diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a408c49 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +FROM rust:latest as build + +WORKDIR /app + +COPY . . + +RUN \ + DEBIAN_FRONTEND=noninteractive \ + apt-get update &&\ + apt-get -y install ca-certificates tzdata &&\ + CARGO_NET_GIT_FETCH_WITH_CLI=true \ + cargo build --release + +# https://hub.docker.com/r/bitnami/minideb +FROM bitnami/minideb:latest + +# microbin will be in /app +WORKDIR /app + +# copy time zone info +COPY --from=build \ + /usr/share/zoneinfo \ + /usr/share/zoneinfo + +COPY --from=build \ + /etc/ssl/certs/ca-certificates.crt \ + /etc/ssl/certs/ca-certificates.crt + +# copy built executable +COPY --from=build \ + /app/target/release/microbin \ + /usr/bin/microbin + +# Expose webport used for the webserver to the docker runtime +EXPOSE 8080 + +ENTRYPOINT ["karton"] diff --git a/src/args.rs b/src/args.rs index e5d4f45..1920658 100644 --- a/src/args.rs +++ b/src/args.rs @@ -17,133 +17,133 @@ pub struct Args { /// If unset, HTTP authentication stays disabled. /// /// WARNING: people opening pastas will have to authenticate too. - #[clap(long, env = "MICROBIN_AUTH_USERNAME")] + #[clap(long, env = "KARTON_AUTH_USERNAME")] pub auth_username: Option, /// Set a password for HTTP authentication. /// If unset, HTTP authentication will not require a password. /// If `auth_username` is unset, this option will not have any effect. - #[clap(long, env = "MICROBIN_AUTH_PASSWORD")] + #[clap(long, env = "KARTON_AUTH_PASSWORD")] pub auth_password: Option, /// Enable the option to make pastas editable. - #[clap(long, env = "MICROBIN_EDITABLE")] + #[clap(long, env = "KARTON_EDITABLE")] pub editable: bool, /// The text displayed in the browser navigation bar. - #[clap(long, env = "MICROBIN_TITLE", default_value = " MicroBin")] + #[clap(long, env = "KARTON_TITLE", default_value = " Karton")] pub title: String, /// The web interfaces' footer text. - #[clap(long, env = "MICROBIN_FOOTER_TEXT")] + #[clap(long, env = "KARTON_FOOTER_TEXT")] pub footer_text: Option, /// Hide the footer of the web interface. - #[clap(long, env = "MICROBIN_HIDE_FOOTER")] + #[clap(long, env = "KARTON_HIDE_FOOTER")] pub hide_footer: bool, /// Hide the header of the web interface. - #[clap(long, env = "MICROBIN_HIDE_HEADER")] + #[clap(long, env = "KARTON_HIDE_HEADER")] pub hide_header: bool, /// Hide the logo in the header. - #[clap(long, env = "MICROBIN_HIDE_LOGO")] + #[clap(long, env = "KARTON_HIDE_LOGO")] pub hide_logo: bool, /// Disable the listing page. - #[clap(long, env = "MICROBIN_NO_LISTING")] + #[clap(long, env = "KARTON_NO_LISTING")] pub no_listing: bool, /// Enable syntax highlighting in pastas. - #[clap(long, env = "MICROBIN_HIGHLIGHTSYNTAX")] + #[clap(long, env = "KARTON_HIGHLIGHTSYNTAX")] pub highlightsyntax: bool, /// The port to which to bind the server. - #[clap(short, long, env = "MICROBIN_PORT", default_value_t = 8080)] + #[clap(short, long, env = "KARTON_PORT", default_value_t = 8080)] pub port: u16, /// The IP adress to bind the server to. - #[clap(short, long, env="MICROBIN_BIND", default_value_t = IpAddr::from([0, 0, 0, 0]))] + #[clap(short, long, env="KARTON_BIND", default_value_t = IpAddr::from([0, 0, 0, 0]))] pub bind: IpAddr, /// Enable the option to create private pastas. - #[clap(long, env = "MICROBIN_PRIVATE")] + #[clap(long, env = "KARTON_PRIVATE")] pub private: bool, /// Disables most css, apart form some inline styles. - #[clap(long, env = "MICROBIN_PURE_HTML")] + #[clap(long, env = "KARTON_PURE_HTML")] pub pure_html: bool, - /// The servers public path, making it possible to run microbin behind a reverse proxy subpath. - #[clap(long, env="MICROBIN_PUBLIC_PATH", default_value_t = PublicUrl(String::from("")))] + /// The servers public path, making it possible to run Karton behind a reverse proxy subpath. + #[clap(long, env="KARTON_PUBLIC_PATH", default_value_t = PublicUrl(String::from("")))] pub public_path: PublicUrl, /// Enable creation of QR codes of pastas. Requires `public_path` to be set. - #[clap(long, env = "MICROBIN_QR")] + #[clap(long, env = "KARTON_QR")] pub qr: bool, /// Disable adding/removing/editing pastas. - #[clap(long, env = "MICROBIN_READONLY")] + #[clap(long, env = "KARTON_READONLY")] pub readonly: bool, /// The amount of worker threads that the server is allowed to have. - #[clap(short, long, env = "MICROBIN_THREADS", default_value_t = 1)] + #[clap(short, long, env = "KARTON_THREADS", default_value_t = 1)] pub threads: u8, /// Sets a time value for the garbage collector. Pastas that aren't accessed for the given /// amount of days will be deleted. Set to 0 to disable garbage collection. - #[clap(short, long, env = "MICROBIN_GC_DAYS", default_value_t = 90)] + #[clap(short, long, env = "KARTON_GC_DAYS", default_value_t = 90)] pub gc_days: u16, /// Enable the option to delete after a given amount of reads. - #[clap(long, env = "MICROBIN_ENABLE_BURN_AFTER")] + #[clap(long, env = "KARTON_ENABLE_BURN_AFTER")] pub enable_burn_after: bool, /// The default amount of reads for the self-delete mechanism. - #[clap(short, long, env = "MICROBIN_DEFAULT_BURN_AFTER", default_value_t = 0)] + #[clap(short, long, env = "KARTON_DEFAULT_BURN_AFTER", default_value_t = 0)] pub default_burn_after: u16, /// Changes the UIs maximum width from 720 pixels to 1080. - #[clap(long, env = "MICROBIN_WIDE")] + #[clap(long, env = "KARTON_WIDE")] pub wide: bool, /// Disable "Never" expiry setting. - #[clap(long, env = "MICROBIN_NO_ETERNAL_PASTA")] + #[clap(long, env = "KARTON_NO_ETERNAL_PASTA")] pub no_eternal_pasta: bool, /// Set the default expiry time value. - #[clap(long, env = "MICROBIN_DEFAULT_EXPIRY", default_value = "24hour")] + #[clap(long, env = "KARTON_DEFAULT_EXPIRY", default_value = "24hour")] pub default_expiry: String, /// Disable file uploading. - #[clap(short, long, env = "MICROBIN_NO_FILE_UPLOAD")] + #[clap(short, long, env = "KARTON_NO_FILE_UPLOAD")] pub no_file_upload: bool, // TODO: replace with simple path. /// Replace built-in CSS file with a CSS file provided by the linked URL. - #[clap(long, env = "MICROBIN_CUSTOM_CSS")] + #[clap(long, env = "KARTON_CUSTOM_CSS")] pub custom_css: Option, /// Replace built-in animal names file with custom names file for pasta links. /// The file must be newline seperated. - #[clap(long, env = "MICROBIN_CUSTOM_NAMES")] + #[clap(long, env = "KARTON_CUSTOM_NAMES")] pub custom_names: Option, /// Enable the use of Hash IDs for shorter URLs instead of animal names. - #[clap(long, env = "MICROBIN_HASH_IDS")] + #[clap(long, env = "KARTON_HASH_IDS")] pub hash_ids: bool, /// Endpoint for /url/ - #[clap(long, env = "MICROBIN_URL_EP", default_value = "url" )] + #[clap(long, env = "KARTON_URL_EP", default_value = "url" )] pub url_endpoint: String, /// Endpoint for /pasta/ - #[clap(long, env = "MICROBIN_PASTA_EP", default_value = "pasta" )] + #[clap(long, env = "KARTON_PASTA_EP", default_value = "pasta" )] pub pasta_endpoint: String, /// Endpoint for /raw/ - #[clap(long, env = "MICROBIN_RAW_EP", default_value = "raw" )] + #[clap(long, env = "KARTON_RAW_EP", default_value = "raw" )] pub raw_endpoint: String, } diff --git a/templates/assets/favicon.svg b/templates/assets/favicon.svg index 9a306c0..fb63341 100644 --- a/templates/assets/favicon.svg +++ b/templates/assets/favicon.svg @@ -1,5 +1,81 @@ - - - - + + + + + + + + + + + + + + + + + + + diff --git a/templates/assets/logo.png b/templates/assets/logo.png index e4e2a30e4675adf101d553c5ab29a06910c5b2f4..37cbc869145bf24f996e868920f8e553ec82b871 100644 GIT binary patch delta 3129 zcmdm_v{zz+ayFjfkCpwHKHUqKdq!Zu_%?Hyu4g5GcUV1 zIk6yBFTW^#_B$IX1_tg^o-U3d6?5Ls&0ZrDDtn+lJ*;Ybgv(0DX4a$Tu8ccvRyk+~ z38!cllz*2~bTyFh)-b%fVvk7UhYbSF89t6e%5D>?%Ied$=gRza@Qrfh+!8Lwwe^d$ zqrx$X1wn_-wU+hCzw@!SzI*rG-n(}#cN_0tBL8e-wcq>y=Fk5;KV!N1(VXIACq4AT zE{UG-nC8sIsCd+m~& z`(W3r30|(XdM~R=CLduHX!>l^pL=yx)Wcm_DldPT94@^&Co6RA2b*o22h}I7^EWqi zZ0J4EzV(^j`Q+7}N;}rgO1}Ln>-=NawL7^j?tH&Fqh#-{PLC?L39naK&O4s%utmBe zkfYAZ=#Xt|(;S~geqXJ^xekUNNSx?=eyUgfryF(Gmrqx@$0Wk_$u~i1oApF7#j2y+ z2fd`4`>*A^aJT(+a`&Wl4hPs094G%>$Z>yVSm^nvmJeOuZPp1bGJIj!w(2K4a}>jk z$?RK{MIQdl+s5&G_oL(&iLd`3Y>;7ydd4UvplkPusUX_!d~It}O*-3C*;kco1e)@* z&;E{@BUZ0p|KeA@feQn}@xXq;muy>}X(?Jr?cm8MJ-UB^X?e7mwUw@WcArqw)3r?c zEbG}N{|g>?I?=g&x>r%<@~1pp%bqX@oMvu$uz2aDJ%_ek?QeX~dC*8f{`VR8mIq~P zmxl**e=g@bxT!?jT{KZR>r{@IYf=sy$^&AUgrs+>TUDSH5CMdg( zuOe2jYPrCjca<`sI;XOy=}onc376%XBVn1Y@w?u@qhX?;9P6ULKMkjLSt;Fl(a7gS@}#7LUeP--&8PKz8*G#fmvL)|Jel3MSS{lX+c}0hdE50d)ASj&bE5wq*|cMm zuh8{A@lTauqFkTqb?f`|yK?!TUgc-w6xh&s>|;ag5f%SS^){f0pxgZ)dcBQu^ETuw-=U&J6;s{%=< zGLKm=%o2_X-&&<}Cp0EpmZxTyeCo`mk4zi~KUK}$dXRb6yu{nDJkBR87ewiwHslp% ztzfw!dRLLf+os=rb?DcRaUw4)Ug;=S2w7$EodBwPk zGeK#>Bl*J$tuLAGtTbKz!|w6p$Di&y#s#p}`}NJeWv2gP%l`PyZnFEU%}pP?;9K>b zZv*cPfhNwiGfzCf8KZF`?|kGN&126P7@~~jEzWMbk#hUh6$SkWjyvMkTT|mMWY){G z++Vo)!Ql{XBl#au2EBg-&p$3b9?0+a+kTdU+jfS&#s64kBy;?-&K^IN`je|X-V=Wf- zi*8(sJ2pp5x&QXd@5x6Z7;~a^1)7d4?cO%UtEg`B=RTfe-1Uzt589P{{&#QN)jctN zf%ns=tc*Nzai+`qXP?hVx6~ZCA>+W&*PCm9`^}!B$bBMDSoddsE{)y4Uw``3)5*z2 zxhqxbr<^Y~`w;cyL(KWbH+qYzdQURR2;aRn>v`1NXbq3`A(P_8n@(rW3E>LSR=2``klOcdi~c$Yx0uUFhrSeV~8@(XIv!G{V7h-g1y4@##UDjzr1O0 zN@vIPRcFkx+qNPs_;*RmJA1)(pahGNpzeZl72e{<-oQWB&EmR~mlTr=LHj zC$hv)*tgekb5v+|ZuDQC1##(iz53}l(yBf%eyY?uP_MlE*|pa_qFk56n>ZB%zFPU; z+9vh>y3X>y6L&DI4qv^qZ}GoXru^IocQ5>G&2U*msa3iH9c;1 zsFahIuL<~Cde+%kNO(a|;9>^xIF0zLv+CDpon4g>c5cf%1|MgRcS{W=Z8nDmAD?pi zljz#QnNk;HmYRC&@ABBkR{dYhbHa^R38#}bKVI>5-}%y~o9?j0NXl`~V-&b4C&75^ z*b{qM_rEhw2z^$N{8OiQoWJb-v*?4T(y~lT=Un>}kbP?1>LSl4Y@Yi3@i~z?e6AeJ z<1^2S);ksGe&9_A(=(Tdb!e%+seNF{H6Ny)-jnHx`44L68?B9Rxhg(MOks&*%L3Pk zcNSSouf^DAi^=xip6y`Q|G4tbLeuPqsZTf6NS@)U@krX<*thtWX*sX%A%#b~vdR`J zyuNVb%4MYwKW)OKb~l8Xyp>|>baK4ryXVp48Cnh}9J=ZaI2!pqYh)A>rVGr`cRB4U z(XHEkJU4pn+K?-qy5~ISc)9l8+7|Wvx6M-1$0q#$gq<#2-O9_}q{$SZbE@>{A{o&p zede?4N)%b1M~VseEtXpsa;0wm|L@&VzOvzKwNfKm3lu3REiwF{=&bDEu~Fmt?sdN|KT+{+klwQF=85`;Nv9vJ$qHTj zwYF&A`JG$jHq|?0w*Reiy>bqFp3g2L&xyD66dr7NV0K}P{K^;7nR$#xCs;ge zu{NUmG?^l{&a%>b>Gh?1`@O6mrJr03Q&lc}s-3qf_i5JI-p7xNlK#s}+GLr2ja<9a zE)~0a4Js>-U+UbiVKie#q4w{8RuLW7X06-K(YLs4^LM5X-l~%IYyb3g zntolICTY)nXVMp!DMwg2UT){uE08dONj?b_GeQezGw~!naPARSSaMyd#JPcwIsZ#a za55{$%c&gf^-2c}SnQ5eFgh^_<}v!^7M|MTGNY5>u*i=Ije-hGqLqBy8xnbHP8{GA zC|aOYqIAH3-R{Vei3c(TqaR%KY5Ci$^Ka71azXASdzYIhPuyL=ZkLh}-C$vyDJbJE z%lgDib*Jp5!lTC}r5K&kl$@lP<&8?1T0&O8(vB)-&UF!Js-N|KvT)PqjK33}6)Nsn z88L#}7hjkYkglw43UNsUnD+SnkJ!D;xrkEMAp7 z5L2>$$@G%D#^V(W$I7s)Hy!&Hv_5#2`1bL4_bk>EGY(DhTqwyo5qHbj2w%JTKQlYe XZtL&ImaJu9U|{fc^>bP0l+XkK%q^^X literal 4402 zcmeAS@N?(olHy`uVBq!ia0y~yU}ykg4mJh`hQoG=rx_RoetNn%hE&A8jjf&_a#ZsD zyqkNi1tu^oQ?e6ceVu6>rEu%+*Z`eL z8S_L}Cj}kLFbU0?6x6e<$)$3~d21H$#Tr?S>?a=IxjXZm`SR}S^4->Vt?!?Cd+(fB zeSmp<{ok+a>;IO1zpn2!C*D`t;jPYIbCKP141U&lUTXOiYC7p9=kNEAw_d$2_x{OL z+j(mHYd_ch-(B;m=hrRa>>nwdo+UqbzU3%U(Lb~5iO{JKw~i$T_v<{Fd~L=R{lFrY zfA`&EbL3BZ$*Uf(_&&*R)yG?bUVbZ-&ZNEIRn?!q!Yn$(f31K+@~x#xH#!8?%!o^5 z(m43!XUL^>3PP0{8?XIe*m2NHciE`Z&2TSakMkstzZZ@yV)?M; zxZY&Wx%ycpx&jB}yJC-M>}?U34t#U^9TN{*h;71&TDI%z5)MzL znH}CJ9hBXz(fiGS=||H^J`N`y=?_zb4tq1$-cYoR@*PJG}!6n&na2cB~M;`Ced)8`GeVx8X4P#N46TJo^@BO z`y3YcCryCSCAPkf&BjerwzG1|##TPYHsuHW9|avQb9lG1+c13RU-mIOL8^Yyy3en( z1Q?g;-8L(`wB(n<_Gjl=C6oW2eCIGd!^-_$6idy)A4wfI*xH^d&1DI^vzdL-4p-$y zFO4$ur6F3WNtQWVww>tvc3!|BZp*34#z_kw6i?4BmY*N7U+aEt$FADtUT<6vT$kG4 zwZo%3a9yXKe2Mau!u6~?yzHO9{B(1(xGyO9;?0zrzv1`KuAV5EnZ3#Tr?ojFn~1a8 zsf$O;)#9x;O#AaXsdn$JpP^h#-V!c(!fg|8FO-YvVVD{ealEgIqvPD868*S|EFahw z^Cw*~JR-Faf&tiDKIInw#A)UC+oe(=L-@}E!ePR-m!kSY*myQ{LtYhZ}1WB5H-exIS*~OMaX60o|3D?VsXh}-RhiWolHlx?_ZIM)%E@o7xy!$C@pGI#=i)bhP83C ztCSn%JD<&;EUtJU@a*5^UCIsW68HT%XUFI<{Cv4;B17h(b2o(ZZbs+*bmdrJR9Spf zkYTl|XUkt@!Mw;2y$MP$r(D=(EV=ske2-a4o64F0-r8lX`KxPWWt36w?gWpe06ob2qvxuBe;qA+?%AA&a?{mAT*N%16o0l#bhT zuWbri=I59GE7IAjSY__iJ5r11uR3Fz*Q545TjyuPr;QnEN}nR+4uml&@G_Lnd9x+@ ze1BE+WN+2!W^=bsTEoMrox4$7!Q$+8?PCWLtQ(Ig<<44p{Y~eYnmOC`44$mGG;PPc zQ*UzOQp1E8xIJ!Ye=gJ#a**`+^q?tq``jgGr*><--S|G(Y5%d{fY@bH91Ai_V&7N& z*ScpkbK-2-o_YT`7tTrN_J00EfMKP6tE{nr$3l&ZF3Lp}x03!&;j=eMp0e)3_gQKV z!Oi_@i(1k zsyG+_QL@r%V~Ei0Jjk%&_%g-^>DJ3$T~cZgpS*SQmY-%lR!mF!vp0XsnYB@PaZpc* z348MC#0`nRI=0R0cV<|__~3?m>W!T(Mb&MBj0du1*=BwOrLF8)45wr_M$hd2)5ETz zENR_%&@IyS;jBDJw}Cl)9*a#Q8j2ZImOFyfuBXd$~D&I z`R|19nQlKn)~&Z z@?Oo}5PF@}WSvjVUDfRMpSFl7OTL*FqGiA4-+Y5_Sz4ErYD)7oZ?9U#-7xV>eS(VZ z^%X^x`@)qOO?0idm;YT8UUBNUc5o<*L$+s&3?tKmBTp(Dj%~W_cS%h9dPg4jaVDXp zm*Gx2fAejoriUH7EcRFN&YVx&o2%Z;+bW`Zz~e1vh}GoMH#2@^Ze`?LQY)PE?4C>X znwp*qbrsBsJZ?YFzL3~>R3Sfu-A3+V)wQ0FJGYeW3es86${p^1aM#gLiKpg^lb>)j znEc&*duo#40l!Prlul$Q94KaZCYlz-n15@tbN;+L2m0imOx0I?F2Hb-Il^$NR#@SN zJi*4&?yzbFMDu>A$yYi&j3`#ZY0JBinExZZ%7Txp3Hl zyQicLPvwUl@91G%p!(7}^VB{z)%_Q)zF>T_RN0yIl)UD>7VS`0(K17tiJp{)F>KO`IUkZPd`T$bi&=4^c3NHe_cQ4(y{D#s zXIZ@afko9~N!guS!nQ40_$~1)L&zlC-0+HPza^gPFL9p15GEPqqp!obdIM8vD6_*- z-C0fMe{CcpB7JXlsWXImZ!%^J@HGp!V$^8pEXzCp>e`aYYc|?$yR-D63`6VW(^_+4 z$`UIkC0S|BVwm^fTz;_9e^G7*YmSDSzf7Iv-}3&Ro-}p;t78ld%j#x6ni;{s!1!e& z%c&Q8Ciu<^s4=%GI$GO2D{yDu(yRJ=_ZF(1N(u_CVmNbc3G;-sb;aLZ_E`5c=s(}R zNy&2V&Z~EyF43KKjITfRVl0Ch;~E)`u*qwGwyd^g>Y4i5b9qyduQ#8Ew$^>GO<}Bz z3JhP0IT-FXy$mXiHDE9(-TzOa+A6-JvfuYy!tEb3=a$&NVYE5QbvM+h;f5mz!`vKJ zh7U8IExcE7+QoR6;*HO-9N!|o?cq7Y@a-_qfg+}kq=ehs3Rd6AT6Z8VkG=6lide&j zKWT#2Y>kIlHe^TdxXN-u`^Ra9FXlZB8F4>U1D8)v<4WdcOfWwBc*D#`)@eMlQ!^!H_*=gh7Ii0U za;KTN?YQa8u!L8^t##$M_sWKD1sn+nq#_Pf@^5SMZ)>}iV0uu7DWbPP^4C|dM#eYl z6G~zvPwt$2K*z0haniJPB4S3ziufPo_QrDFwx9RNZBY|T;*Nbw&1Ggh&um`)M&n#? znQOQE$@f8b8|81r)|}>K5Ipc!fN@T0`9XtEr*}TN9G)}ND*@{o zw_iFp=iL@9?P@cPl}VL}?=sGvcTUbJ&0mtL>n7Q1%iy-`XoUW8|*NSmeLzaLF41pW|v0p_3kbw|!7|UeL4I zmr3XQ`ss-wLJWC~vfSGn3buN7VH{|E7XRmCj_dWRItWhFA zr@GFBgb<+wshm}7+;4?giYVOJV99BgGwr#NC%6OT+O%ZekpA)-OoScw2bpXQmCx&B7o}WGb+W!0=O^Mt|oNsmSf6))JV$qOy zRb&!)$)CaUp(V-lM(T6j`(MrnTQNHX3v>x2cpd&%eUYQ#>Aytz*d5EQ1&msqc-6%e z8|>z-wqQ!R`b9H8$0EO;_j=+@*Zh5tzq*Cbt&v^N6vCvDyHR(K+C+3 z?yGK)VAfw-P|2`V`Q=id-EGGsCgwS&T+v!oe(bHadYW|1_RlwFOY?p{rM2)#Z^PY8 zn@ZPjdZ)7{!=&msPoaM)&Y)_^iO&_lo9G`z-WBSBtuLKebM59{W zH5ZAfHgp*Nl(b;^!Nj|I7eiqG3xNX%!n-DH6FSDQO~4@~VA5gnyxq6huh0EAX?woV zM=BjBF|gPha} zwcWMfKPAPQF@9ON>^_9 zpBQ&@S;G5@nJN2@YwItPZc6S}WXraYyY#uOVmBA_*7(o27CvTttg%CM`YNHN1-5zL xf|X9Xt0>7fWk0i + + + + + + + + + + + + + + + + + + + diff --git a/templates/assets/water.css b/templates/assets/water.css index 7f627da..422b511 100644 --- a/templates/assets/water.css +++ b/templates/assets/water.css @@ -1 +1,626 @@ -:root{--background-body:#202b38;--background:#161f27;--background-alt:#1a242f;--selection:#1c76c5;--text-main:#dbdbdb;--text-bright:#fff;--text-muted:#a9b1ba;--links:#41adff;--focus:rgba(0,150,191,0.67);--border:#526980;--code:#ffbe85;--animation-duration:0.1s;--button-base:#0c151c;--button-hover:#040a0f;--scrollbar-thumb:var(--button-hover);--scrollbar-thumb-hover:#000;--form-placeholder:#a9a9a9;--form-text:#fff;--variable:#d941e2;--highlight:#efdb43;--select-arrow:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='63' width='117' fill='%23efefef'%3E%3Cpath d='M115 2c-1-2-4-2-5 0L59 53 7 2a4 4 0 00-5 5l54 54 2 2 3-2 54-54c2-1 2-4 0-5z'/%3E%3C/svg%3E")}html{scrollbar-color:#040a0f #202b38;scrollbar-color:var(--scrollbar-thumb) var(--background-body);scrollbar-width:thin}body{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,Segoe UI Emoji,Apple Color Emoji,Noto Color Emoji,sans-serif;line-height:1.4;max-width:800px;margin:20px auto;padding:0 10px;word-wrap:break-word;color:#dbdbdb;color:var(--text-main);background:#202b38;background:var(--background-body);text-rendering:optimizeLegibility}button,input,textarea{transition:background-color .1s linear,border-color .1s linear,color .1s linear,box-shadow .1s linear,transform .1s ease;transition:background-color var(--animation-duration) linear,border-color var(--animation-duration) linear,color var(--animation-duration) linear,box-shadow var(--animation-duration) linear,transform var(--animation-duration) ease}h1{font-size:2.2em;margin-top:0}h1,h2,h3,h4,h5,h6{margin-bottom:12px;margin-top:24px}h1,h2,h3,h4,h5,h6,strong{color:#fff;color:var(--text-bright)}b,h1,h2,h3,h4,h5,h6,strong,th{font-weight:600}q:after,q:before{content:none}blockquote,q{border-left:4px solid rgba(0,150,191,.67);border-left:4px solid var(--focus);margin:1.5em 0;padding:.5em 1em;font-style:italic}blockquote>footer{font-style:normal;border:0}address,blockquote cite{font-style:normal}a[href^=mailto\:]:before{content:"📧 "}a[href^=tel\:]:before{content:"📞 "}a[href^=sms\:]:before{content:"💬 "}mark{background-color:#efdb43;background-color:var(--highlight);border-radius:2px;padding:0 2px;color:#000}a>code,a>strong{color:inherit}button,input[type=button],input[type=checkbox],input[type=radio],input[type=range],input[type=reset],input[type=submit],select{cursor:pointer}input,select{display:block}[type=checkbox],[type=radio]{display:initial}button,input,select,textarea{color:#fff;color:var(--form-text);background-color:#161f27;background-color:var(--background);font-family:inherit;font-size:inherit;margin-right:6px;margin-bottom:6px;padding:10px;border:none;border-radius:6px;outline:none}button,input[type=button],input[type=reset],input[type=submit]{background-color:#0c151c;background-color:var(--button-base);padding-right:30px;padding-left:30px}button:hover,input[type=button]:hover,input[type=reset]:hover,input[type=submit]:hover{background:#040a0f;background:var(--button-hover)}input[type=color]{min-height:2rem;padding:8px;cursor:pointer}input[type=checkbox],input[type=radio]{height:1em;width:1em}input[type=radio]{border-radius:100%}input{vertical-align:top}label{vertical-align:middle;margin-bottom:4px;display:inline-block}button,input:not([type=checkbox]):not([type=radio]),input[type=range],select,textarea{-webkit-appearance:none}textarea{display:block;margin-right:0;box-sizing:border-box;resize:vertical}textarea:not([cols]){width:100%}textarea:not([rows]){min-height:40px;height:140px}select{background:#161f27 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='63' width='117' fill='%23efefef'%3E%3Cpath d='M115 2c-1-2-4-2-5 0L59 53 7 2a4 4 0 00-5 5l54 54 2 2 3-2 54-54c2-1 2-4 0-5z'/%3E%3C/svg%3E") calc(100% - 12px) 50%/12px no-repeat;background:var(--background) var(--select-arrow) calc(100% - 12px) 50%/12px no-repeat;padding-right:35px}select::-ms-expand{display:none}select[multiple]{padding-right:10px;background-image:none;overflow-y:auto}button:focus,input:focus,select:focus,textarea:focus{box-shadow:0 0 0 2px rgba(0,150,191,.67);box-shadow:0 0 0 2px var(--focus)}button:active,input[type=button]:active,input[type=checkbox]:active,input[type=radio]:active,input[type=range]:active,input[type=reset]:active,input[type=submit]:active{transform:translateY(2px)}button:disabled,input:disabled,select:disabled,textarea:disabled{cursor:not-allowed;opacity:.5}::-moz-placeholder{color:#a9a9a9;color:var(--form-placeholder)}:-ms-input-placeholder{color:#a9a9a9;color:var(--form-placeholder)}::-ms-input-placeholder{color:#a9a9a9;color:var(--form-placeholder)}::placeholder{color:#a9a9a9;color:var(--form-placeholder)}fieldset{border:1px solid rgba(0,150,191,.67);border:1px solid var(--focus);border-radius:6px;margin:0 0 12px;padding:10px}legend{font-size:.9em;font-weight:600}input[type=range]{margin:10px 0;padding:10px 0;background:transparent}input[type=range]:focus{outline:none}input[type=range]::-webkit-slider-runnable-track{width:100%;height:9.5px;-webkit-transition:.2s;transition:.2s;background:#161f27;background:var(--background);border-radius:3px}input[type=range]::-webkit-slider-thumb{box-shadow:0 1px 1px #000,0 0 1px #0d0d0d;height:20px;width:20px;border-radius:50%;background:#526980;background:var(--border);-webkit-appearance:none;margin-top:-7px}input[type=range]:focus::-webkit-slider-runnable-track{background:#161f27;background:var(--background)}input[type=range]::-moz-range-track{width:100%;height:9.5px;-moz-transition:.2s;transition:.2s;background:#161f27;background:var(--background);border-radius:3px}input[type=range]::-moz-range-thumb{box-shadow:1px 1px 1px #000,0 0 1px #0d0d0d;height:20px;width:20px;border-radius:50%;background:#526980;background:var(--border)}input[type=range]::-ms-track{width:100%;height:9.5px;background:transparent;border-color:transparent;border-width:16px 0;color:transparent}input[type=range]::-ms-fill-lower,input[type=range]::-ms-fill-upper{background:#161f27;background:var(--background);border:.2px solid #010101;border-radius:3px;box-shadow:1px 1px 1px #000,0 0 1px #0d0d0d}input[type=range]::-ms-thumb{box-shadow:1px 1px 1px #000,0 0 1px #0d0d0d;border:1px solid #000;height:20px;width:20px;border-radius:50%;background:#526980;background:var(--border)}input[type=range]:focus::-ms-fill-lower,input[type=range]:focus::-ms-fill-upper{background:#161f27;background:var(--background)}a{text-decoration:none;color:#41adff;color:var(--links)}a:hover{text-decoration:underline}code,samp,time{background:#161f27;background:var(--background);color:#ffbe85;color:var(--code);padding:2.5px 5px;border-radius:6px;font-size:1em}pre>code{padding:10px;display:block;overflow-x:auto}var{color:#d941e2;color:var(--variable);font-style:normal;font-family:monospace}kbd{background:#161f27;background:var(--background);border:1px solid #526980;border:1px solid var(--border);border-radius:2px;color:#dbdbdb;color:var(--text-main);padding:2px 4px}img,video{max-width:100%;height:auto}hr{border:none;border-top:1px solid #526980;border-top:1px solid var(--border)}table{border-collapse:collapse;margin-bottom:10px;width:100%;table-layout:fixed}table caption,td,th{text-align:left}td,th{padding:6px;vertical-align:top;word-wrap:break-word}thead{border-bottom:1px solid #526980;border-bottom:1px solid var(--border)}tfoot{border-top:1px solid #526980;border-top:1px solid var(--border)}tbody tr:nth-child(2n){background-color:#161f27;background-color:var(--background)}tbody tr:nth-child(2n) button{background-color:#1a242f;background-color:var(--background-alt)}tbody tr:nth-child(2n) button:hover{background-color:#202b38;background-color:var(--background-body)}::-webkit-scrollbar{height:10px;width:10px}::-webkit-scrollbar-track{background:#161f27;background:var(--background);border-radius:6px}::-webkit-scrollbar-thumb{background:#040a0f;background:var(--scrollbar-thumb);border-radius:6px}::-webkit-scrollbar-thumb:hover{background:#000;background:var(--scrollbar-thumb-hover)}::-moz-selection{background-color:#1c76c5;background-color:var(--selection);color:#fff;color:var(--text-bright)}::selection{background-color:#1c76c5;background-color:var(--selection);color:#fff;color:var(--text-bright)}details{display:flex;flex-direction:column;align-items:flex-start;background-color:#1a242f;background-color:var(--background-alt);padding:10px 10px 0;margin:1em 0;border-radius:6px;overflow:hidden}details[open]{padding:10px}details>:last-child{margin-bottom:0}details[open] summary{margin-bottom:10px}summary{display:list-item;background-color:#161f27;background-color:var(--background);padding:10px;margin:-10px -10px 0;cursor:pointer;outline:none}summary:focus,summary:hover{text-decoration:underline}details>:not(summary){margin-top:0}summary::-webkit-details-marker{color:#dbdbdb;color:var(--text-main)}dialog{background-color:#1a242f;background-color:var(--background-alt);color:#dbdbdb;color:var(--text-main);border-radius:6px;border:#526980;border-color:var(--border);padding:10px 30px}dialog>header:first-child{background-color:#161f27;background-color:var(--background);border-radius:6px 6px 0 0;margin:-10px -30px 10px;padding:10px;text-align:center}dialog::-webkit-backdrop{background:rgba(0,0,0,.61);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}dialog::backdrop{background:rgba(0,0,0,.61);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}footer{border-top:1px solid #526980;border-top:1px solid var(--border);padding-top:10px;color:#a9b1ba;color:var(--text-muted)}body>footer{margin-top:40px}@media print{body,button,code,details,input,pre,summary,textarea{background-color:#fff}button,input,textarea{border:1px solid #000}body,button,code,footer,h1,h2,h3,h4,h5,h6,input,pre,strong,summary,textarea{color:#000}summary::marker{color:#000}summary::-webkit-details-marker{color:#000}tbody tr:nth-child(2n){background-color:#f2f2f2}a{color:#00f;text-decoration:underline}} \ No newline at end of file +/* + * This is (basically) water.css. + * + * repo: https://github.com/kognise/water.css + * + * The license: + * + * The MIT License (MIT) + * + * Copyright © 2019 Kognise + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the “Software”), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +:root { + --background-body:#4a4a55; + --background:#383844; + --background-alt:#242438; + --selection:#23bf7c; + --text-main:#dfdfef; + --text-bright:#f7f7ff; + --text-muted:#878797; + --links:#28db8f; + --focus:#299465df; + --border:#676773; + --code:var(--text-main); + --animation-duration:0.1s; + --button-base:#299465; + --button-hover:#23bf7c; + --scrollbar-thumb:var(--button-hover); + --scrollbar-thumb-hover:#000; + --form-placeholder:#a9a9a9; + --form-text:#fff; + --variable:#d941e2; + --highlight:#efdb43; + --select-arrow:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='63' width='117' fill='%23efefef'%3E%3Cpath d='M115 2c-1-2-4-2-5 0L59 53 7 2a4 4 0 00-5 5l54 54 2 2 3-2 54-54c2-1 2-4 0-5z'/%3E%3C/svg%3E") +} +html { + scrollbar-color:#040a0f #202b38; + scrollbar-color:var(--scrollbar-thumb) var(--background-body); + scrollbar-width:thin +} +body { + font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,Segoe UI Emoji,Apple Color Emoji,Noto Color Emoji,sans-serif; + line-height:1.4; + max-width:800px; + margin:20px auto; + padding:0 10px; + word-wrap:break-word; + color:#dbdbdb; + color:var(--text-main); + background:#202b38; + background:var(--background-body); + text-rendering:optimizeLegibility +} +button, +input, +textarea { + transition:background-color .1s linear,border-color .1s linear,color .1s linear,box-shadow .1s linear,transform .1s ease; + transition:background-color var(--animation-duration) linear,border-color var(--animation-duration) linear,color var(--animation-duration) linear,box-shadow var(--animation-duration) linear,transform var(--animation-duration) ease +} +h1 { + font-size:2.2em; + margin-top:0 +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin-bottom:12px; + margin-top:24px +} +h1, +h2, +h3, +h4, +h5, +h6, +strong { + color:#fff; + color:var(--text-bright) +} +b, +h1, +h2, +h3, +h4, +h5, +h6, +strong, +th { + font-weight:600 +} +q:after, +q:before { + content:none +} +blockquote, +q { + border-left:4px solid rgba(0,150,191,.67); + border-left:4px solid var(--focus); + margin:1.5em 0; + padding:.5em 1em; + font-style:italic +} +blockquote>footer { + font-style:normal; + border:0 +} +address, +blockquote cite { + font-style:normal +} +a[href^=mailto\:]:before { + content:"📧 " +} +a[href^=tel\:]:before { + content:"📞 " +} +a[href^=sms\:]:before { + content:"💬 " +} +mark { + background-color:#efdb43; + background-color:var(--highlight); + border-radius:2px; + padding:0 2px; + color:#000 +} +a>code, +a>strong { + color:inherit +} +button, +input[type=button], +input[type=checkbox], +input[type=radio], +input[type=range], +input[type=reset], +input[type=submit], +select { + cursor:pointer +} +input, +select { + display:block +} +[type=checkbox], +[type=radio] { + display:initial +} +button, +input, +select, +textarea { + color:#fff; + color:var(--form-text); + background-color:#161f27; + background-color:var(--background); + font-family:inherit; + font-size:inherit; + margin-right:6px; + margin-bottom:6px; + padding:10px; + border:none; + border-radius:6px; + outline:none +} +button, +input[type=button], +input[type=reset], +input[type=submit] { + background-color:#0c151c; + background-color:var(--button-base); + padding-right:30px; + padding-left:30px +} +button:hover, +input[type=button]:hover, +input[type=reset]:hover, +input[type=submit]:hover { + background:#040a0f; + background:var(--button-hover) +} +input[type=color] { + min-height:2rem; + padding:8px; + cursor:pointer +} +input[type=checkbox], +input[type=radio] { + height:1em; + width:1em +} +input[type=radio] { + border-radius:100% +} +input { + vertical-align:top +} +label { + vertical-align:middle; + margin-bottom:4px; + display:inline-block +} +button, +input:not([type=checkbox]):not([type=radio]), +input[type=range], +select, +textarea { + -webkit-appearance:none +} +textarea { + display:block; + margin-right:0; + box-sizing:border-box; + resize:vertical +} +textarea:not([cols]) { + width:100% +} +textarea:not([rows]) { + min-height:40px; + height:140px +} +select { + background:#161f27 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='63' width='117' fill='%23efefef'%3E%3Cpath d='M115 2c-1-2-4-2-5 0L59 53 7 2a4 4 0 00-5 5l54 54 2 2 3-2 54-54c2-1 2-4 0-5z'/%3E%3C/svg%3E") calc(100% - 12px) 50%/12px no-repeat; + background:var(--background) var(--select-arrow) calc(100% - 12px) 50%/12px no-repeat; + padding-right:35px +} +select::-ms-expand { + display:none +} +select[multiple] { + padding-right:10px; + background-image:none; + overflow-y:auto +} +button:focus, +input:focus, +select:focus, +textarea:focus { + box-shadow:0 0 0 2px rgba(0,150,191,.67); + box-shadow:0 0 0 2px var(--focus) +} +button:active, +input[type=button]:active, +input[type=checkbox]:active, +input[type=radio]:active, +input[type=range]:active, +input[type=reset]:active, +input[type=submit]:active { + transform:translateY(2px) +} +button:disabled, +input:disabled, +select:disabled, +textarea:disabled { + cursor:not-allowed; + opacity:.5 +} +::-moz-placeholder { + color:#a9a9a9; + color:var(--form-placeholder) +} +:-ms-input-placeholder { + color:#a9a9a9; + color:var(--form-placeholder) +} +::-ms-input-placeholder { + color:#a9a9a9; + color:var(--form-placeholder) +} +::placeholder { + color:#a9a9a9; + color:var(--form-placeholder) +} +fieldset { + border:1px solid rgba(0,150,191,.67); + border:1px solid var(--focus); + border-radius:6px; + margin:0 0 12px; + padding:10px +} +legend { + font-size:.9em; + font-weight:600 +} +input[type=range] { + margin:10px 0; + padding:10px 0; + background:transparent +} +input[type=range]:focus { + outline:none +} +input[type=range]::-webkit-slider-runnable-track { + width:100%; + height:9.5px; + -webkit-transition:.2s; + transition:.2s; + background:#161f27; + background:var(--background); + border-radius:3px +} +input[type=range]::-webkit-slider-thumb { + box-shadow:0 1px 1px #000,0 0 1px #0d0d0d; + height:20px; + width:20px; + border-radius:50%; + background:#526980; + background:var(--border); + -webkit-appearance:none; + margin-top:-7px +} +input[type=range]:focus::-webkit-slider-runnable-track { + background:#161f27; + background:var(--background) +} +input[type=range]::-moz-range-track { + width:100%; + height:9.5px; + -moz-transition:.2s; + transition:.2s; + background:#161f27; + background:var(--background); + border-radius:3px +} +input[type=range]::-moz-range-thumb { + box-shadow:1px 1px 1px #000,0 0 1px #0d0d0d; + height:20px; + width:20px; + border-radius:50%; + background:#526980; + background:var(--border) +} +input[type=range]::-ms-track { + width:100%; + height:9.5px; + background:transparent; + border-color:transparent; + border-width:16px 0; + color:transparent +} +input[type=range]::-ms-fill-lower, +input[type=range]::-ms-fill-upper { + background:#161f27; + background:var(--background); + border:.2px solid #010101; + border-radius:3px; + box-shadow:1px 1px 1px #000,0 0 1px #0d0d0d +} +input[type=range]::-ms-thumb { + box-shadow:1px 1px 1px #000,0 0 1px #0d0d0d; + border:1px solid #000; + height:20px; + width:20px; + border-radius:50%; + background:#526980; + background:var(--border) +} +input[type=range]:focus::-ms-fill-lower, +input[type=range]:focus::-ms-fill-upper { + background:#161f27; + background:var(--background) +} +a { + text-decoration:none; + color:#41adff; + color:var(--links) +} +a:hover { + text-decoration:underline +} +code, +samp, +time { + background:#161f27; + background:var(--background); + color:#ffbe85; + color:var(--code); + padding:2.5px 5px; + border-radius:6px; + font-size:1em +} +pre>code { + padding:10px; + display:block; + overflow-x:auto +} +var { + color:#d941e2; + color:var(--variable); + font-style:normal; + font-family:monospace +} +kbd { + background:#161f27; + background:var(--background); + border:1px solid #526980; + border:1px solid var(--border); + border-radius:2px; + color:#dbdbdb; + color:var(--text-main); + padding:2px 4px +} +img, +video { + max-width:100%; + height:auto +} +hr { + border:none; + border-top:1px solid #526980; + border-top:1px solid var(--border) +} +table { + border-collapse:collapse; + margin-bottom:10px; + width:100%; + table-layout:fixed +} +table caption, +td, +th { + text-align:left +} +td, +th { + padding:6px; + vertical-align:top; + word-wrap:break-word +} +thead { + border-bottom:1px solid #526980; + border-bottom:1px solid var(--border) +} +tfoot { + border-top:1px solid #526980; + border-top:1px solid var(--border) +} +tbody tr:nth-child(2n) { + background-color:#161f27; + background-color:var(--background) +} +tbody tr:nth-child(2n) button { + background-color:#1a242f; + background-color:var(--background-alt) +} +tbody tr:nth-child(2n) button:hover { + background-color:#202b38; + background-color:var(--background-body) +} +::-webkit-scrollbar { + height:10px; + width:10px +} +::-webkit-scrollbar-track { + background:#161f27; + background:var(--background); + border-radius:6px +} +::-webkit-scrollbar-thumb { + background:#040a0f; + background:var(--scrollbar-thumb); + border-radius:6px +} +::-webkit-scrollbar-thumb:hover { + background:#000; + background:var(--scrollbar-thumb-hover) +} +::-moz-selection { + background-color:#1c76c5; + background-color:var(--selection); + color:#fff; + color:var(--text-bright) +} +::selection { + background-color:#1c76c5; + background-color:var(--selection); + color:#fff; + color:var(--text-bright) +} +details { + display:flex; + flex-direction:column; + align-items:flex-start; + background-color:#1a242f; + background-color:var(--background-alt); + padding:10px 10px 0; + margin:1em 0; + border-radius:6px; + overflow:hidden +} +details[open] { + padding:10px +} +details>:last-child { + margin-bottom:0 +} +details[open] summary { + margin-bottom:10px +} +summary { + display:list-item; + background-color:#161f27; + background-color:var(--background); + padding:10px; + margin:-10px -10px 0; + cursor:pointer; + outline:none +} +summary:focus, +summary:hover { + text-decoration:underline +} +details>:not(summary) { + margin-top:0 +} +summary::-webkit-details-marker { + color:#dbdbdb; + color:var(--text-main) +} +dialog { + background-color:#1a242f; + background-color:var(--background-alt); + color:#dbdbdb; + color:var(--text-main); + border-radius:6px; + border:#526980; + border-color:var(--border); + padding:10px 30px +} +dialog>header:first-child { + background-color:#161f27; + background-color:var(--background); + border-radius:6px 6px 0 0; + margin:-10px -30px 10px; + padding:10px; + text-align:center +} +dialog::-webkit-backdrop { + background:rgba(0,0,0,.61); + -webkit-backdrop-filter:blur(4px); + backdrop-filter:blur(4px) +} +dialog::backdrop { + background:rgba(0,0,0,.61); + -webkit-backdrop-filter:blur(4px); + backdrop-filter:blur(4px) +} +footer { + border-top:1px solid #526980; + border-top:1px solid var(--border); + padding-top:10px; + color:#a9b1ba; + color:var(--text-muted) +} +body>footer { + margin-top:40px +} +@media print { + body, + button, + code, + details, + input, + pre, + summary, + textarea { + background-color:#fff + } + button, + input, + textarea { + border:1px solid #000 + } + body, + button, + code, + footer, + h1, + h2, + h3, + h4, + h5, + h6, + input, + pre, + strong, + summary, + textarea { + color:#000 + } + summary::marker { + color:#000 + } + summary::-webkit-details-marker { + color:#000 + } + tbody tr:nth-child(2n) { + background-color:#f2f2f2 + } + a { + color:#00f; + text-decoration:underline + } +} + diff --git a/templates/footer.html b/templates/footer.html index de2895d..dcac7b4 100644 --- a/templates/footer.html +++ b/templates/footer.html @@ -3,7 +3,7 @@

{% if args.footer_text.as_ref().is_none() %} - MicroBin by Dániel Szabó and the FOSS Community. + Karton by Schrottkatze, based on MicroBin by Dániel Szabó and the FOSS Community. Let's keep the Web compact, accessible and humane! {%- else %} {{ args.footer_text.as_ref().unwrap() }} diff --git a/templates/header.html b/templates/header.html index b7895b6..8f49088 100644 --- a/templates/header.html +++ b/templates/header.html @@ -44,15 +44,13 @@ {% if !args.hide_logo %} - - - + {%- endif %} - MicroBin + {{ args.title }} New diff --git a/templates/index.html b/templates/index.html index 791f827..cdae99f 100644 --- a/templates/index.html +++ b/templates/index.html @@ -179,11 +179,14 @@ {% endif %} {% if args.readonly %} - + + {%- else %} - + + {%- endif %}

@@ -246,4 +249,4 @@ } -{% include "footer.html" %} \ No newline at end of file +{% include "footer.html" %} From f1de42e5c0615db7f565173cd1d6c6cd8fbc8c0c Mon Sep 17 00:00:00 2001 From: Jade Date: Sun, 5 Mar 2023 15:23:11 +0100 Subject: [PATCH 73/92] updated readme a bit --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1daedc8..5660369 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ -# MicroBin +# Karton -This is a fork of [MicroBin](https://github.com/szabodanika/microbin) intends to fix some bugs and add some features to MicroBin. +A small, rusty pastebin with URL shortener functionality. -I deliberately removed docker support for now. - -Please do not ask for help in the issues of the original MicroBin repository, I'd be happy to help you with any problems here though. +This is a fork of [MicroBin](https://github.com/szabodanika/microbin). ## TODOs: From b313b5ce73c79d135ff3be219dcba973ab8490d7 Mon Sep 17 00:00:00 2001 From: Jade Date: Sun, 5 Mar 2023 15:37:48 +0100 Subject: [PATCH 74/92] updated readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5660369..e7dfd1c 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ A small, rusty pastebin with URL shortener functionality. +The github repository is a mirror of [this gitlab repository](https://gitlab.com/obsidianical/microbin). + This is a fork of [MicroBin](https://github.com/szabodanika/microbin). ## TODOs: From 86e41865bb0d3d6321bb492bb3b81521207a0902 Mon Sep 17 00:00:00 2001 From: Jade Date: Sun, 5 Mar 2023 15:43:49 +0100 Subject: [PATCH 75/92] ignored result --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 64fccb2..7be8825 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # will have compiled files and executables debug/ target/ +result/ # These are backup files generated by rustfmt **/*.rs.bk @@ -9,4 +10,4 @@ target/ # MSVC Windows builds of rustc generate these, which store debugging information *.pdb -pasta_data/* \ No newline at end of file +pasta_data/* From 8039fe75a21bf2386ad501b685897e65eed55a3a Mon Sep 17 00:00:00 2001 From: Jade Date: Sun, 5 Mar 2023 15:44:28 +0100 Subject: [PATCH 76/92] fixed gitignore result ignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7be8825..515ea81 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ # will have compiled files and executables debug/ target/ -result/ +result # These are backup files generated by rustfmt **/*.rs.bk From 91568a1590eea5403e0bb1ad8abf78dff1c5f1e7 Mon Sep 17 00:00:00 2001 From: Jade Date: Sun, 5 Mar 2023 16:07:08 +0100 Subject: [PATCH 77/92] updated readme --- README.md | 72 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index e7dfd1c..b41097a 100644 --- a/README.md +++ b/README.md @@ -6,47 +6,65 @@ The github repository is a mirror of [this gitlab repository](https://gitlab.com This is a fork of [MicroBin](https://github.com/szabodanika/microbin). +## Features + +- Animal names (by default) or custom namefiles instead of just hashes (though hashes are an option too!) +- File and image uploads +- raw text serving +- URL shortening +- QR codes +- Listing and removing pastas (though currently everyone can do that) +- Expiration times +- Editable pastas +- Syntax highlighting +- Styling via [water.css](https://github.com/kognise/water.css) +- Customizable endpoints + ## TODOs: -- [ ] Rebrand - - [ ] New name and logo - - [ ] New README +- [x] removed light mode + +- [x] Rebrand + - [x] New name and logo + - [x] New README + - [ ] installation guides - [ ] Website - [ ] Official central instance - [ ] Donation thing? - [ ] Distribution - [ ] nixpkgs - - [ ] crates.io + - [x] crates.io - [ ] Docker - [ ] Various other distribution specific repositories? - [ ] Quality - [ ] Tests - - [ ] Proper design stuff + - [x] New theme + - [ ] Proper database (_seriously, json isn't a database_) + - [ ] Proper auth and permissions (_so a single user can also use it and send links_) + - [ ] multi-user + - [x] Click logo/name to get to root -- [ ] Proper database (_seriously, json isn't a database_) -- [ ] Configurable endpoints (_so a url shortener isn't lengthened by /url/_) - - [ ] make root page a redirect and root based redirect -- [ ] Proper auth and permissions (_so a single user can also use it and send links_) - - [ ] multi-user -- [ ] Customizable keys (_so you can make fixed pastas_) - - [x] Customizable wordset -- [ ] Non-env/args configurations -- [ ] encrypted pastas -- [ ] image embeds - - [x] in pasta view - - [ ] easy to copy image embed url -- [ ] Markdown pastas -- [ ] further endpoint configuration - - [x] customizable `pasta`, `url` and `raw` endpoints - - [ ] simplified media embed endpoints (/file/$id or /embed/$id by default? maybe with compression?) - - [ ] disable remove -- [x] Click logo/name to get to root -- [ ] switch to other template engine -- [ ] Move frontend interactive code to rust as well +- [ ] Customizability + - [ ] Customizable keys (_so you can make fixed pastas_) + - [x] Customizable wordset + - [ ] Non-env/args configurations + - [ ] further endpoint configuration + - [x] customizable `pasta`, `url` and `raw` endpoints + - [ ] simplified media embed endpoints (/file/$id or /embed/$id by default? maybe with compression?) + - [ ] disable remove + - [ ] make root page a redirect and root based redirect + - [ ] easy to customize logo, icon etc. + - [ ] simplified themeing (only colors etc) + +- [ ] Features + - [ ] encrypted pastas + - [ ] image embeds + - [x] in pasta view + - [ ] easy to copy image embed url + - [ ] Markdown pastas -- [x] removed light mode ## Contact @@ -54,3 +72,5 @@ This is a fork of [MicroBin](https://github.com/szabodanika/microbin). This fork of MicroBin was created by [Schrottkatze](https://schrottkatze.de). Join [the matrix room](https://matrix.to/#/#s10e-microbin:matrix.org) to chat! + +Contact me via e-mail at [contact@schrottkatze.de](mailto:contact@schrottkatze.de). From 01eb19e7324a60f4c768ef8cb65ca5e37a147bec Mon Sep 17 00:00:00 2001 From: Jade Date: Sun, 5 Mar 2023 16:08:26 +0100 Subject: [PATCH 78/92] removed unnecessary import --- src/endpoints/pasta.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/endpoints/pasta.rs b/src/endpoints/pasta.rs index 67a7677..1017f3b 100644 --- a/src/endpoints/pasta.rs +++ b/src/endpoints/pasta.rs @@ -7,7 +7,7 @@ use crate::util::misc::remove_expired; use crate::AppState; use crate::util::pasta_id_converter::CONVERTER; -use actix_web::{get, web, HttpResponse}; +use actix_web::{web, HttpResponse}; use askama::Template; use std::time::{SystemTime, UNIX_EPOCH}; From 75755052c3618e37a110f5c1cf57bfdca3df7829 Mon Sep 17 00:00:00 2001 From: Jade Date: Sun, 5 Mar 2023 16:10:19 +0100 Subject: [PATCH 79/92] removed keyword --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 56898cf..f177ff3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ description = "Simple, performant, configurable, entirely self-contained Pastebi readme = "README.md" homepage = "https://gitlab.com/obsidianical/microbin" repository = "https://gitlab.com/obsidianical/microbin" -keywords = ["pastebin", "pastabin", "karton", "microbin", "actix", "selfhosted"] +keywords = ["pastebin", "karton", "microbin", "actix", "selfhosted"] categories = ["pastebins"] [dependencies] From c5b0a8ef79c9999884bd8330c33ce141f5cac76c Mon Sep 17 00:00:00 2001 From: Jade Date: Sun, 5 Mar 2023 17:02:18 +0100 Subject: [PATCH 80/92] docker! --- Dockerfile | 8 ++++---- README.md | 2 +- flake.nix | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index a408c49..4fb8ae3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:latest as build +FROM docker.io/rust:latest as build WORKDIR /app @@ -12,7 +12,7 @@ RUN \ cargo build --release # https://hub.docker.com/r/bitnami/minideb -FROM bitnami/minideb:latest +FROM docker.io/bitnami/minideb:latest # microbin will be in /app WORKDIR /app @@ -28,8 +28,8 @@ COPY --from=build \ # copy built executable COPY --from=build \ - /app/target/release/microbin \ - /usr/bin/microbin + /app/target/release/karton \ + /usr/bin/karton # Expose webport used for the webserver to the docker runtime EXPOSE 8080 diff --git a/README.md b/README.md index b41097a..0a32b51 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ This is a fork of [MicroBin](https://github.com/szabodanika/microbin). - [ ] Distribution - [ ] nixpkgs - [x] crates.io - - [ ] Docker + - [x] Docker hub - [ ] Various other distribution specific repositories? - [ ] Quality diff --git a/flake.nix b/flake.nix index d455ca4..c5fcff0 100644 --- a/flake.nix +++ b/flake.nix @@ -14,7 +14,7 @@ { defaultPackage = naersk-lib.buildPackage ./.; devShell = with pkgs; mkShell { - buildInputs = [ cargo rustc rustfmt pre-commit rustPackages.clippy cargo-watch ]; + buildInputs = [ cargo rustc rustfmt pre-commit rustPackages.clippy cargo-watch podman ]; RUST_SRC_PATH = rustPlatform.rustLibSrc; }; }); From 5d0f73a5f3992153a329489a5373303455dac3fa Mon Sep 17 00:00:00 2001 From: Jade Date: Sun, 5 Mar 2023 19:35:07 +0100 Subject: [PATCH 81/92] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'naersk/nixpkgs': 'github:NixOS/nixpkgs/8c66bd1b68f4708c90dcc97c6f7052a5a7b33257' (2023-02-16) → 'github:NixOS/nixpkgs/f5ffd5787786dde3a8bf648c7a1b5f78c4e01abb' (2023-03-03) • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/8c66bd1b68f4708c90dcc97c6f7052a5a7b33257' (2023-02-16) → 'github:NixOS/nixpkgs/f5ffd5787786dde3a8bf648c7a1b5f78c4e01abb' (2023-03-03) --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index cecfde6..9e09da8 100644 --- a/flake.lock +++ b/flake.lock @@ -21,11 +21,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1676549890, - "narHash": "sha256-sq/WcOEAl7gWrrfGkWdnyYazRyTf+enEim/o6LOQzI8=", + "lastModified": 1677852945, + "narHash": "sha256-liiVJjkBTuBTAkRW3hrI8MbPD2ImYzwUpa7kvteiKhM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "8c66bd1b68f4708c90dcc97c6f7052a5a7b33257", + "rev": "f5ffd5787786dde3a8bf648c7a1b5f78c4e01abb", "type": "github" }, "original": { @@ -35,11 +35,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1676549890, - "narHash": "sha256-sq/WcOEAl7gWrrfGkWdnyYazRyTf+enEim/o6LOQzI8=", + "lastModified": 1677852945, + "narHash": "sha256-liiVJjkBTuBTAkRW3hrI8MbPD2ImYzwUpa7kvteiKhM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "8c66bd1b68f4708c90dcc97c6f7052a5a7b33257", + "rev": "f5ffd5787786dde3a8bf648c7a1b5f78c4e01abb", "type": "github" }, "original": { From e3a5527a8c13a50d7b90b27125cf579f6199047c Mon Sep 17 00:00:00 2001 From: Jade Date: Mon, 6 Mar 2023 12:12:47 +0100 Subject: [PATCH 82/92] README: reorganize TODOs to roadmap --- README.md | 98 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 0a32b51..448654f 100644 --- a/README.md +++ b/README.md @@ -20,52 +20,78 @@ This is a fork of [MicroBin](https://github.com/szabodanika/microbin). - Styling via [water.css](https://github.com/kognise/water.css) - Customizable endpoints -## TODOs: +## Roadmap -- [x] removed light mode +This is only a rough time guide for what to get done by which version, nothing fixed. +### v2.0 + +- [x] Removed light mode - [x] Rebrand - [x] New name and logo - [x] New README - - [ ] installation guides - - [ ] Website - - [ ] Official central instance - - [ ] Donation thing? - -- [ ] Distribution - - [ ] nixpkgs - - [x] crates.io - - [x] Docker hub - - [ ] Various other distribution specific repositories? - -- [ ] Quality - - [ ] Tests - [x] New theme - - [ ] Proper database (_seriously, json isn't a database_) - - [ ] Proper auth and permissions (_so a single user can also use it and send links_) - - [ ] multi-user - - [x] Click logo/name to get to root +- [x] Distribution on crates.io +- [x] Distribution on Docker hub +- [x] Image embedding in pasta page +- [x] Custom names file +- [x] Click logo/name to get to root -- [ ] Customizability - - [ ] Customizable keys (_so you can make fixed pastas_) - - [x] Customizable wordset - - [ ] Non-env/args configurations - - [ ] further endpoint configuration - - [x] customizable `pasta`, `url` and `raw` endpoints - - [ ] simplified media embed endpoints (/file/$id or /embed/$id by default? maybe with compression?) - - [ ] disable remove - - [ ] make root page a redirect and root based redirect - - [ ] easy to customize logo, icon etc. - - [ ] simplified themeing (only colors etc) +### v2.1 -- [ ] Features - - [ ] encrypted pastas - - [ ] image embeds - - [x] in pasta view - - [ ] easy to copy image embed url - - [ ] Markdown pastas +- [ ] Installation guides +- [ ] Copying embed urls more easily (some button for that) +- [ ] Api for requesting customized url info +- [ ] Config file support +- [ ] Markdown pastas +### v2.2 +- [ ] Proper docs +- [ ] Improved rustdoc +- [ ] Non-web client library +- [ ] CLI client +- [ ] Easier customization of instance names and logos +- [ ] Easier basic themeing + - [ ] Colors + - [ ] Corner rounding + +### v2.3 + +- [ ] Encrypted pastas + +### v3.0 + +- [ ] Deprecate JSON db, replace with SQLite +- [ ] Rework internal data structures + - [ ] Map custom keys to ids + - [ ] Make hash ids, names and custom keys usable at once +- [ ] Users + - [ ] Reporting pastas + - [ ] Admin panel +- [ ] Improve remove api +- [ ] Status/health/info improvements + - [ ] Storage thats left + - [ ] Db status + - [ ] Pastas on the instance + - [ ] Users + - [ ] Errors + +### future + +- [ ] Federation + - [ ] Requesting pastas from other instances + - [ ] When cli is complete, set default instance to route requests over + - [ ] Fine grained permissions +- [ ] Postgresql db support +- [ ] Pasta comments? + +### not related to features, therefor not versioned + +- [ ] Official central instance +- [ ] Donation setup? +- [ ] Distribution on nixpkgs +- [ ] Website ## Contact From c83a775ac28de6c847931bda68c9c23995a66606 Mon Sep 17 00:00:00 2001 From: Jade Date: Thu, 9 Mar 2023 20:05:23 +0100 Subject: [PATCH 83/92] add direnv directory to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 515ea81..a930d6b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ debug/ target/ result +.direnv/ # These are backup files generated by rustfmt **/*.rs.bk From 181ebb3a63145428f031336c6079d38aee613ee0 Mon Sep 17 00:00:00 2001 From: Jade Date: Thu, 9 Mar 2023 20:05:57 +0100 Subject: [PATCH 84/92] Fix XSS attack (again) Now escaping only for slashes, since HTML is apparently case insensitive and using a script closing tag that wasn't entirely lowercase bypassed the earlier fix. --- src/pasta.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pasta.rs b/src/pasta.rs index b771c66..38a215a 100644 --- a/src/pasta.rs +++ b/src/pasta.rs @@ -155,7 +155,7 @@ impl Pasta { self.content .replace('`', "\\`") .replace('$', "\\$") - .replace(" Date: Thu, 9 Mar 2023 20:44:38 +0100 Subject: [PATCH 85/92] add nix flake installation guide --- README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/README.md b/README.md index 448654f..1d0ced4 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,53 @@ This is a fork of [MicroBin](https://github.com/szabodanika/microbin). - Styling via [water.css](https://github.com/kognise/water.css) - Customizable endpoints +## Installation guide + +Karton is available on [Docker hub](https://hub.docker.com/r/schrottkatze/karton), [crates.io](https://crates.io/crates/karton) and using the nix flake. + +The only "officially supported" (I will actively debug and search for the problem) method is the last one using nix flakes. + +### Installation via the nix flake + +Add the repository to your inputs. + +```nix + karton.url = "git+https://gitlab.com/obsidianical/microbin.git"; +``` + +```nix +# microbin.nix +{ inputs, config, pkgs, ... }: +{ + environment.systemPackages = [ inputs.karton.defaultPackage."x86_64-linux" ]; + systemd.services.karton = { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + environment = { + # set environment variables to configure karton + KARTON_HASH_IDS = ""; + KARTON_EDITABLE = ""; + KARTON_PRIVATE = ""; + KARTON_HIGHLIGHTSYNTAX = ""; + # adjust this to your domain + KARTON_PUBLIC_PATH = "https://example.org"; + KARTON_QR = ""; + # configure endpoints to be shorter + KARTON_URL_EP = "u"; + KARTON_RAW_EP = "r"; + KARTON_PASTA_EP = "p"; + }; + script = "${inputs.karton.defaultPackage."x86_64-linux"}/bin/karton"; + # register a simple systemd service + serviceConfig = { + Type = "simple"; + RootDirectory="/"; + WorkingDirectory = "/karton"; + }; + }; +} +``` + ## Roadmap This is only a rough time guide for what to get done by which version, nothing fixed. @@ -40,6 +87,7 @@ This is only a rough time guide for what to get done by which version, nothing f ### v2.1 - [ ] Installation guides + - [x] nix flake - [ ] Copying embed urls more easily (some button for that) - [ ] Api for requesting customized url info - [ ] Config file support From 42aceb2a01e9a265768798299faafb388d5c99a0 Mon Sep 17 00:00:00 2001 From: Jade Date: Fri, 10 Mar 2023 08:18:11 +0100 Subject: [PATCH 86/92] Fix error codes, handle bad requests for creation Fix that invalid UTF-8 or continuing the read mid-character crashes server thread. --- src/endpoints/create.rs | 18 +++++++++++++++--- src/endpoints/edit.rs | 15 +++++++++++---- src/endpoints/errors.rs | 10 +++++++--- src/endpoints/pasta.rs | 22 ++++++++++++++++------ src/endpoints/qr.rs | 8 ++++++-- src/endpoints/remove.rs | 8 ++++++-- templates/error.html | 6 +++--- templates/header.html | 2 +- 8 files changed, 65 insertions(+), 24 deletions(-) diff --git a/src/endpoints/create.rs b/src/endpoints/create.rs index d3b618f..a725984 100644 --- a/src/endpoints/create.rs +++ b/src/endpoints/create.rs @@ -5,6 +5,8 @@ use crate::util::misc::is_valid_url; use crate::util::pasta_id_converter::CONVERTER; use crate::{AppState, Pasta, ARGS}; use actix_multipart::Multipart; +use actix_web::http::StatusCode; +use actix_web::web::{Bytes, BytesMut, BufMut}; use actix_web::{get, web, Error, HttpResponse, Responder}; use askama::Template; use bytesize::ByteSize; @@ -14,6 +16,8 @@ use rand::Rng; use std::io::Write; use std::time::{SystemTime, UNIX_EPOCH}; +use super::errors::ErrorTemplate; + #[derive(Template)] #[template(path = "index.html")] struct IndexTemplate<'a> { @@ -115,12 +119,20 @@ pub async fn create( } } "content" => { - let mut content = String::from(""); + let mut content = BytesMut::new(); while let Some(chunk) = field.try_next().await? { - content.push_str(std::str::from_utf8(&chunk).unwrap().to_string().as_str()); + content.put(chunk); } if !content.is_empty() { - new_pasta.content = content; + new_pasta.content = match String::from_utf8(content.to_vec()) { + Ok(v) => v, + Err(e) => return Ok(HttpResponse::BadRequest() + .content_type("text/html") + .body(ErrorTemplate { + status_code: StatusCode::BAD_REQUEST, + args: &ARGS + }.render().unwrap())), + }; new_pasta.pasta_type = if is_valid_url(new_pasta.content.as_str()) { String::from("url") diff --git a/src/endpoints/edit.rs b/src/endpoints/edit.rs index bebf25c..bfa4dba 100644 --- a/src/endpoints/edit.rs +++ b/src/endpoints/edit.rs @@ -6,6 +6,7 @@ use crate::util::misc::remove_expired; use crate::util::pasta_id_converter::CONVERTER; use crate::{AppState, Pasta, ARGS}; use actix_multipart::Multipart; +use actix_web::http::StatusCode; use actix_web::{get, post, web, Error, HttpResponse}; use askama::Template; use futures::TryStreamExt; @@ -42,9 +43,12 @@ pub async fn get_edit(data: web::Data, id: web::Path) -> HttpR } } - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()) } #[post("/edit/{id}")] @@ -97,7 +101,10 @@ pub async fn post_edit( } } - Ok(HttpResponse::Ok() + Ok(HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap())) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap())) } diff --git a/src/endpoints/errors.rs b/src/endpoints/errors.rs index 04626b4..744ede5 100644 --- a/src/endpoints/errors.rs +++ b/src/endpoints/errors.rs @@ -1,4 +1,4 @@ -use actix_web::{Error, HttpResponse}; +use actix_web::{Error, HttpResponse, http::StatusCode}; use askama::Template; use crate::args::{Args, ARGS}; @@ -6,11 +6,15 @@ use crate::args::{Args, ARGS}; #[derive(Template)] #[template(path = "error.html")] pub struct ErrorTemplate<'a> { + pub status_code: StatusCode, pub args: &'a Args, } pub async fn not_found() -> Result { - Ok(HttpResponse::Ok() + Ok(HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap())) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap())) } diff --git a/src/endpoints/pasta.rs b/src/endpoints/pasta.rs index 1017f3b..39ba5a6 100644 --- a/src/endpoints/pasta.rs +++ b/src/endpoints/pasta.rs @@ -7,6 +7,7 @@ use crate::util::misc::remove_expired; use crate::AppState; use crate::util::pasta_id_converter::CONVERTER; +use actix_web::http::StatusCode; use actix_web::{web, HttpResponse}; use askama::Template; use std::time::{SystemTime, UNIX_EPOCH}; @@ -77,9 +78,12 @@ pub async fn getpasta(data: web::Data, id: web::Path) -> HttpR // otherwise // send pasta not found error - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()) } /// Endpoint for redirection. @@ -136,17 +140,23 @@ pub async fn redirecturl(data: web::Data, id: web::Path) -> Ht return response; // send error if we're trying to open a non-url pasta as a redirect } else { - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()); + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()); } } // otherwise // send pasta not found error - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()) } /// Endpoint to request pasta as raw file. diff --git a/src/endpoints/qr.rs b/src/endpoints/qr.rs index 6639470..73dcb9b 100644 --- a/src/endpoints/qr.rs +++ b/src/endpoints/qr.rs @@ -5,6 +5,7 @@ use crate::util::hashids::to_u64 as hashid_to_u64; use crate::util::misc::{self, remove_expired}; use crate::AppState; use crate::util::pasta_id_converter::CONVERTER; +use actix_web::http::StatusCode; use actix_web::{get, web, HttpResponse}; use askama::Template; @@ -63,7 +64,10 @@ pub async fn getqr(data: web::Data, id: web::Path) -> HttpResp // otherwise // send pasta not found error - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()) } diff --git a/src/endpoints/remove.rs b/src/endpoints/remove.rs index ce0c407..1dbe997 100644 --- a/src/endpoints/remove.rs +++ b/src/endpoints/remove.rs @@ -1,3 +1,4 @@ +use actix_web::http::StatusCode; use actix_web::{get, web, HttpResponse}; use crate::args::ARGS; @@ -58,7 +59,10 @@ pub async fn remove(data: web::Data, id: web::Path) -> HttpRes remove_expired(&mut pastas); - HttpResponse::Ok() + HttpResponse::NotFound() .content_type("text/html") - .body(ErrorTemplate { args: &ARGS }.render().unwrap()) + .body(ErrorTemplate { + status_code: StatusCode::NOT_FOUND, + args: &ARGS + }.render().unwrap()) } diff --git a/templates/error.html b/templates/error.html index 806229e..a0c007c 100644 --- a/templates/error.html +++ b/templates/error.html @@ -1,10 +1,10 @@ {% include "header.html" %}
-

404

-Not Found +

{{ status_code.as_u16() }}

+{{ status_code.canonical_reason().unwrap_or("Unknown error") }}

Go Home

-{% include "footer.html" %} \ No newline at end of file +{% include "footer.html" %} diff --git a/templates/header.html b/templates/header.html index 8f49088..7154bdf 100644 --- a/templates/header.html +++ b/templates/header.html @@ -2,7 +2,7 @@ - MicroBin + {{ args.title }} From f3ca7e3328c2fde3819a290e81319d6c672650ed Mon Sep 17 00:00:00 2001 From: Jade Date: Fri, 10 Mar 2023 08:22:16 +0100 Subject: [PATCH 87/92] bump version to 2.0.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f177ff3..6432d52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "karton" -version = "2.0.0" +version = "2.0.1" edition = "2021" authors = ["Jade ", "Daniel Szabo "] license = "BSD-3-Clause" From 1f69a77a032cd1c79253cc1a0222ece451f54075 Mon Sep 17 00:00:00 2001 From: Jade Date: Fri, 10 Mar 2023 08:23:56 +0100 Subject: [PATCH 88/92] update Cargo.lock --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index db1ad9e..bab4773 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1161,7 +1161,7 @@ dependencies = [ [[package]] name = "karton" -version = "2.0.0" +version = "2.0.1" dependencies = [ "actix-files", "actix-multipart", From 808ffd4964d423d33075e666d9de4c478a6be5b4 Mon Sep 17 00:00:00 2001 From: Jade Date: Fri, 10 Mar 2023 08:39:24 +0100 Subject: [PATCH 89/92] fix some warnings --- src/endpoints/create.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/endpoints/create.rs b/src/endpoints/create.rs index a725984..917e959 100644 --- a/src/endpoints/create.rs +++ b/src/endpoints/create.rs @@ -6,7 +6,7 @@ use crate::util::pasta_id_converter::CONVERTER; use crate::{AppState, Pasta, ARGS}; use actix_multipart::Multipart; use actix_web::http::StatusCode; -use actix_web::web::{Bytes, BytesMut, BufMut}; +use actix_web::web::{BytesMut, BufMut}; use actix_web::{get, web, Error, HttpResponse, Responder}; use askama::Template; use bytesize::ByteSize; @@ -126,7 +126,7 @@ pub async fn create( if !content.is_empty() { new_pasta.content = match String::from_utf8(content.to_vec()) { Ok(v) => v, - Err(e) => return Ok(HttpResponse::BadRequest() + Err(_) => return Ok(HttpResponse::BadRequest() .content_type("text/html") .body(ErrorTemplate { status_code: StatusCode::BAD_REQUEST, From 5002f11bf360e4508fc73c28fa0aa0f80bf0713d Mon Sep 17 00:00:00 2001 From: Jade Date: Wed, 3 May 2023 22:42:56 +0200 Subject: [PATCH 90/92] update readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1d0ced4..506cbb6 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,8 @@ This is only a rough time guide for what to get done by which version, nothing f - [ ] Installation guides - [x] nix flake - [ ] Copying embed urls more easily (some button for that) -- [ ] Api for requesting customized url info + - [ ] "raw" if it isn't an image, if it is "embed" +- [ ] Api for requesting customized api info - [ ] Config file support - [ ] Markdown pastas From 768c8c60b8d698bfda154a67d46b13b5cbfa9197 Mon Sep 17 00:00:00 2001 From: Jade Date: Thu, 4 May 2023 10:47:08 +0200 Subject: [PATCH 91/92] update TODOs --- README.md | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 506cbb6..1ebd02f 100644 --- a/README.md +++ b/README.md @@ -86,39 +86,49 @@ This is only a rough time guide for what to get done by which version, nothing f ### v2.1 +*Focus: Modularity, Programmability, APIs* + - [ ] Installation guides - [x] nix flake -- [ ] Copying embed urls more easily (some button for that) - - [ ] "raw" if it isn't an image, if it is "embed" -- [ ] Api for requesting customized api info -- [ ] Config file support -- [ ] Markdown pastas +- [ ] Api for requesting customized api info (.well-known endpoint) +- [ ] Non-web client library +- [ ] CLI client +- [ ] better remove api and granularity ### v2.2 -- [ ] Proper docs -- [ ] Improved rustdoc -- [ ] Non-web client library -- [ ] CLI client -- [ ] Easier customization of instance names and logos +*Focus: Configurability* + +- [ ] Config file support - [ ] Easier basic themeing - [ ] Colors - [ ] Corner rounding +- [ ] Proper docs +- [ ] Improved rustdoc +- [ ] Easier customization of instance names and logos ### v2.3 +*Focus: Better pastas* + - [ ] Encrypted pastas +- [ ] Copying embed urls more easily (some button for that) + - [ ] "raw" if it isn't an image, if it is "embed" +- [ ] Markdown pastas ### v3.0 -- [ ] Deprecate JSON db, replace with SQLite -- [ ] Rework internal data structures - - [ ] Map custom keys to ids - - [ ] Make hash ids, names and custom keys usable at once -- [ ] Users - - [ ] Reporting pastas - - [ ] Admin panel -- [ ] Improve remove api +- [ ] entirely new frontend +- [ ] Authentication + - [ ] basic logins + - [ ] oidc + - [ ] Moderation + - [ ] Permission system + - [ ] admin panel +- [ ] Deprecate JSON db, replace with SQLite and postgres support + - [ ] Rework internal data structures + - [ ] Map custom keys to ids + - [ ] Make hash ids, names and custom keys usable at once - [ ] Status/health/info improvements - [ ] Storage thats left - [ ] Db status From 68996acd5437b4d84c9092bd106f4c60c2ac7e34 Mon Sep 17 00:00:00 2001 From: Jade Date: Thu, 4 May 2023 11:55:43 +0200 Subject: [PATCH 92/92] update TODOs (again) --- README.md | 85 ------------------------------------------------------- TODO.md | 54 +++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 85 deletions(-) create mode 100644 TODO.md diff --git a/README.md b/README.md index 1ebd02f..b5f6a08 100644 --- a/README.md +++ b/README.md @@ -67,91 +67,6 @@ Add the repository to your inputs. } ``` -## Roadmap - -This is only a rough time guide for what to get done by which version, nothing fixed. - -### v2.0 - -- [x] Removed light mode -- [x] Rebrand - - [x] New name and logo - - [x] New README - - [x] New theme -- [x] Distribution on crates.io -- [x] Distribution on Docker hub -- [x] Image embedding in pasta page -- [x] Custom names file -- [x] Click logo/name to get to root - -### v2.1 - -*Focus: Modularity, Programmability, APIs* - -- [ ] Installation guides - - [x] nix flake -- [ ] Api for requesting customized api info (.well-known endpoint) -- [ ] Non-web client library -- [ ] CLI client -- [ ] better remove api and granularity - -### v2.2 - -*Focus: Configurability* - -- [ ] Config file support -- [ ] Easier basic themeing - - [ ] Colors - - [ ] Corner rounding -- [ ] Proper docs -- [ ] Improved rustdoc -- [ ] Easier customization of instance names and logos - -### v2.3 - -*Focus: Better pastas* - -- [ ] Encrypted pastas -- [ ] Copying embed urls more easily (some button for that) - - [ ] "raw" if it isn't an image, if it is "embed" -- [ ] Markdown pastas - -### v3.0 - -- [ ] entirely new frontend -- [ ] Authentication - - [ ] basic logins - - [ ] oidc - - [ ] Moderation - - [ ] Permission system - - [ ] admin panel -- [ ] Deprecate JSON db, replace with SQLite and postgres support - - [ ] Rework internal data structures - - [ ] Map custom keys to ids - - [ ] Make hash ids, names and custom keys usable at once -- [ ] Status/health/info improvements - - [ ] Storage thats left - - [ ] Db status - - [ ] Pastas on the instance - - [ ] Users - - [ ] Errors - -### future - -- [ ] Federation - - [ ] Requesting pastas from other instances - - [ ] When cli is complete, set default instance to route requests over - - [ ] Fine grained permissions -- [ ] Postgresql db support -- [ ] Pasta comments? - -### not related to features, therefor not versioned - -- [ ] Official central instance -- [ ] Donation setup? -- [ ] Distribution on nixpkgs -- [ ] Website - ## Contact This fork of MicroBin was created by [Schrottkatze](https://schrottkatze.de). diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..559543e --- /dev/null +++ b/TODO.md @@ -0,0 +1,54 @@ +# TODO lists + +these are just rough guides tho + +## v2.1 + +- [ ] customizable endpoints + - [ ] create + - [ ] edit + - [ ] info + - [ ] get pastas + - [ ] remove +- [ ] improve remove endpoint + - [ ] disable it +- [ ] client library + - [ ] request .well-known data + - [ ] support most endpoints +- [ ] karton cli + +## v3.0 + +- [ ] internal rewrite & docs +- [ ] design new frontend +- [ ] switch to yew + - [ ] using client lib +- [ ] theme and general config files + - [ ] unified theme format + - [ ] no env configs anymore if possible +- [ ] proper dbs + - [ ] sqlite + - [ ] postgres +- [ ] apis/endpoints + - [ ] IDs, name IDs AND user/pastaname + - [ ] root (and admin) user for root level pastas +- [ ] status/instance health admin dashboard and ap + - [ ] storage + - [ ] db status + - [ ] how up to date + - [ ] stats (users etc) + - [ ] errors + - [ ] loading speeds, performance monitor? + - [ ] memory use +- [ ] auth + - [ ] general auth + - [ ] oidc + - [ ] permssion system & api keys + - [ ] only allow some other users to open pasta + - [ ] access control and editing + - [ ] password protected pastas too +- [ ] features for pastas + - [ ] pw protection + - [ ] better editor + - [ ] markdown pastas + - [ ] optional, opt-in commenting