Compare commits

..

13 commits
v2.0 ... master

Author SHA1 Message Date
68996acd54 update TODOs (again) 2023-05-04 11:55:43 +02:00
768c8c60b8 update TODOs 2023-05-04 10:47:08 +02:00
5002f11bf3 update readme 2023-05-03 22:42:56 +02:00
808ffd4964 fix some warnings 2023-03-10 08:39:24 +01:00
1f69a77a03 update Cargo.lock 2023-03-10 08:23:56 +01:00
f3ca7e3328 bump version to 2.0.1 2023-03-10 08:22:16 +01:00
42aceb2a01 Fix error codes, handle bad requests for creation
Fix that invalid UTF-8 or continuing the read mid-character crashes
server thread.
2023-03-10 08:18:11 +01:00
1652a850b8 add nix flake installation guide 2023-03-09 20:44:38 +01:00
181ebb3a63 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.
2023-03-09 20:05:57 +01:00
c83a775ac2 add direnv directory to gitignore 2023-03-09 20:05:23 +01:00
e3a5527a8c README: reorganize TODOs to roadmap 2023-03-06 12:12:47 +01:00
5d0f73a5f3 flake.lock: Update
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)
2023-03-05 19:35:07 +01:00
c5b0a8ef79 docker! 2023-03-05 17:02:18 +01:00
17 changed files with 174 additions and 78 deletions

1
.gitignore vendored
View file

@ -3,6 +3,7 @@
debug/
target/
result
.direnv/
# These are backup files generated by rustfmt
**/*.rs.bk

2
Cargo.lock generated
View file

@ -1161,7 +1161,7 @@ dependencies = [
[[package]]
name = "karton"
version = "2.0.0"
version = "2.0.1"
dependencies = [
"actix-files",
"actix-multipart",

View file

@ -1,6 +1,6 @@
[package]
name = "karton"
version = "2.0.0"
version = "2.0.1"
edition = "2021"
authors = ["Jade <jade@schrottkatze.de>", "Daniel Szabo <daniel.szabo99@outlook.com>"]
license = "BSD-3-Clause"

View file

@ -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

View file

@ -20,52 +20,52 @@ This is a fork of [MicroBin](https://github.com/szabodanika/microbin).
- Styling via [water.css](https://github.com/kognise/water.css)
- Customizable endpoints
## TODOs:
## Installation guide
- [x] removed light mode
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.
- [x] Rebrand
- [x] New name and logo
- [x] New README
- [ ] installation guides
- [ ] Website
- [ ] Official central instance
- [ ] Donation thing?
The only "officially supported" (I will actively debug and search for the problem) method is the last one using nix flakes.
- [ ] Distribution
- [ ] nixpkgs
- [x] crates.io
- [ ] Docker
- [ ] Various other distribution specific repositories?
### Installation via the nix flake
- [ ] 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
- [ ] 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
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";
};
};
}
```
## Contact

54
TODO.md Normal file
View file

@ -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

View file

@ -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": {

View file

@ -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;
};
});

View file

@ -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::{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(_) => 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")

View file

@ -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<AppState>, id: web::Path<String>) -> 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()))
}

View file

@ -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<HttpResponse, Error> {
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()))
}

View file

@ -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<AppState>, id: web::Path<String>) -> 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<AppState>, id: web::Path<String>) -> 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.

View file

@ -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<AppState>, id: web::Path<String>) -> 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())
}

View file

@ -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<AppState>, id: web::Path<String>) -> 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())
}

View file

@ -155,7 +155,7 @@ impl Pasta {
self.content
.replace('`', "\\`")
.replace('$', "\\$")
.replace("</script", "<\\/script")
.replace('/', "\\/")
}
}

View file

@ -1,10 +1,10 @@
{% include "header.html" %}
<br>
<h2>404</h2>
<b>Not Found</b>
<h2>{{ status_code.as_u16() }}</h2>
<b>{{ status_code.canonical_reason().unwrap_or("Unknown error") }}</b>
<br>
<br>
<a href="{{ args.public_path }}/"> Go Home</a>
<br>
<br>
{% include "footer.html" %}
{% include "footer.html" %}

View file

@ -2,7 +2,7 @@
<html>
<head>
<title>MicroBin</title>
<title>{{ args.title }}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">