diff --git a/assets/css/global.css b/assets/css/global.css new file mode 100644 index 0000000..52848df --- /dev/null +++ b/assets/css/global.css @@ -0,0 +1,132 @@ +#top { + margin-top: 2vw; + margin-left: 15vw; + margin-right: 15vw; +} +@font-face { + font-family: "Hack Nerd Font"; + src: url(/assets/ttf/HNF-Reg.ttf); +} +@font-face { + font-family: "Jetbrains Mono"; + src: url(/assets/ttf/JBM.ttf); +} +:root { + --text-color: #8941ad; + --term-color: #4af626; +} +body { + color: var(--term-color); + background-color: black; + font-family: "Jetbrains Mono"; +} +#link-container a { + text-decoration: none; + color: var(--term-color); +} +#link-container { + display: flex; + gap: 4vw; +} +hr { + margin-top: 1px; + color: var(--term-color); +} + +/* + CSS styling for guestbook +*/ +#entries { + align-items: center; + gap: 10px; + margin-top: 10px; + display: flex; + flex-direction: column; +} +.guest-entry { + width: 100%; +} +bu { + font-weight: bold; + text-decoration: underline; +} +.entry-header { + display: flex; + justify-content: space-between; +} +.entry-body { + font-size: 14px; + overflow: auto; + word-wrap: break-word; +} +a { + text-decoration: none; + color: var(--term-color); +} +#post-container { + text-align: center; + padding: 5px; + margin: auto; + margin-top: 10px; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-between; + flex: 0 0 auto; +} +input, +textarea { + margin-left: 5vw; +} +.break { + flex-basis: 100%; + height: 0; +} +.link:hover { + background-color: var(--term-color); + color: black; +} +label { + text-align: left; + clear: both; + float: left; +} + +/* + CSS styling for services page. +*/ + +:root { + --sin-padding: 5px; +} +#service-containers { + display: flex; + gap: 10px; + flex-wrap: wrap; + width: 100%; + justify-content: center; +} +.service-link { + color: var(--term-color); + vertical-align: middle; +} +.service-icon { + vertical-align: middle; +} +.service-title { + align-items: center; + gap: 5px; + display: flex; + margin: 0; + justify-content: center; +} +.service-container { + padding: var(--sin-padding); + padding-top: 0px; + flex-shrink: 0; + border: 1px solid var(--term-color); + flex-basis: 22%; +} +.service-container hr { + margin-left: calc(-1 * var(--sin-padding)); + margin-right: calc(-1 * var(--sin-padding)); +} diff --git a/assets/img/authelia.png b/assets/img/authelia.png new file mode 100644 index 0000000..52c5aea Binary files /dev/null and b/assets/img/authelia.png differ diff --git a/assets/img/dn42.png b/assets/img/dn42.png new file mode 100644 index 0000000..8f4d63b Binary files /dev/null and b/assets/img/dn42.png differ diff --git a/assets/img/jellyfin.png b/assets/img/jellyfin.png new file mode 100644 index 0000000..ae08791 Binary files /dev/null and b/assets/img/jellyfin.png differ diff --git a/assets/img/jellyseerr.ico b/assets/img/jellyseerr.ico new file mode 100644 index 0000000..dbca29f Binary files /dev/null and b/assets/img/jellyseerr.ico differ diff --git a/assets/img/lain.png b/assets/img/lain.png deleted file mode 100644 index 5c70f81..0000000 Binary files a/assets/img/lain.png and /dev/null differ diff --git a/assets/img/mail.png b/assets/img/mail.png new file mode 100644 index 0000000..7910223 Binary files /dev/null and b/assets/img/mail.png differ diff --git a/assets/img/woodpecker.svg b/assets/img/woodpecker.svg new file mode 100644 index 0000000..1cd49a8 --- /dev/null +++ b/assets/img/woodpecker.svg @@ -0,0 +1,10 @@ + + + + diff --git a/assets/pgp/andre.txt b/assets/pgp/andre.txt new file mode 100644 index 0000000..801c67e --- /dev/null +++ b/assets/pgp/andre.txt @@ -0,0 +1,13 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEZs80XRYJKwYBBAHaRw8BAQdAFEbr22JHklXkyOgqDp/o/IgngPN6Sck3Mjih +LLDjwTy0GEFuZHJlIDxvcGVucmNAcG9zdGVvLmRlPoiTBBMWCgA7FiEEIe1Ep7aw +ZGGQHzkyFuz+3MRZea4FAmbR+S0CGwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcC +F4AACgkQFuz+3MRZea7GewD/cEexNFi6y0eZqiWduihvyrJjnD8mDKQ8W5+Nt23v +60IA/2AdbuULXtJ2wsww/3VpIjN22AJdTTZQq9SEgLbhqfwLuDgEZs80XRIKKwYB +BAGXVQEFAQEHQL53gX/5GbufLJYAcb+nAT59LCaPFXk5FgmoOZTxic49AwEIB4h4 +BBgWCgAgFiEEIe1Ep7awZGGQHzkyFuz+3MRZea4FAmbPNF0CGwwACgkQFuz+3MRZ +ea754AEAkjXsfyVYCBBUHiBKF8m1aEtWx1xFwUlXXQ6AX0gBYHsBAM+okBmzAqQr +1GhAgSqafxHs9a/aNdINQVp9APQiD5QK +=+1X6 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/assets/pgp/hex.txt b/assets/pgp/hex.txt new file mode 100644 index 0000000..6e0e0d3 --- /dev/null +++ b/assets/pgp/hex.txt @@ -0,0 +1,53 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +5jeQGlf9A7iXF80g +=1mQ+ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/assets/ttf/JBM.ttf b/assets/ttf/JBM.ttf new file mode 100644 index 0000000..3fce55d Binary files /dev/null and b/assets/ttf/JBM.ttf differ diff --git a/src/main.rs b/src/main.rs index 56d6ef5..ed397fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,26 +3,25 @@ mod logger; extern crate rocket; extern crate rocket_dyn_templates; -use rocket::response::content::RawJson; -use rocket::{get, post, launch, build, routes}; use rocket::fs::FileServer; -use rocket_dyn_templates::{Template, context}; -use rocket::serde::{Deserialize, Serialize, json::Json}; +use rocket::serde::{json::Json, Deserialize, Serialize}; +use rocket::{build, get, launch, post, routes}; +use rocket_dyn_templates::{context, Template}; use chrono::Local; use std::borrow::Cow; +use std::fs::read_to_string; +use std::fs::File; use std::io::Write; use std::path::Path; -use std::fs::File; -use std::fs::read_to_string; -use serde_json::{Value, json}; +use serde_json::{json, Value}; -use crate::logger::iwakulog::{LogLevel, log}; +use crate::logger::iwakulog::{log, LogLevel}; -const ASSETS_DIR: &str = "./assets"; -const GUEST_MESSAGES: &str = "./guests.json"; +const ASSETS_DIR: &str = "./assets"; +const GUEST_MESSAGES: &str = "./guests.json"; const DATE_TIME_FORMAT: &str = "%Y-%m-%d | %H:%M"; #[derive(Serialize, Deserialize)] @@ -32,7 +31,6 @@ struct GuestMessage<'r> { body: Cow<'r, str>, } - fn check_file(path: &str) -> bool { Path::new(path).exists() } @@ -46,7 +44,7 @@ fn read_guest_messages() -> Result> { fn post_guest_message(name: &str, body: &str) { let mut guest_json = match read_guest_messages() { Ok(x) => x, - Err(x) => panic!("Error while reading guest messages: {x:?}") + Err(x) => panic!("Error while reading guest messages: {x:?}"), }; let messages = guest_json["messages"] .as_array_mut() @@ -58,10 +56,21 @@ fn post_guest_message(name: &str, body: &str) { "date": date.timestamp(), })); let mut file = File::create(GUEST_MESSAGES).expect("Couldn't read msgs"); - file.write_all(guest_json.to_string().as_bytes()).expect("wah"); + file.write_all(guest_json.to_string().as_bytes()) + .expect("wah"); +} +#[get("/abuse")] +fn abuse() -> Template { + Template::render("abuse", context! {}) +} +#[get("/post")] +fn post() -> Template { + Template::render("post", context! {}) +} +#[get("/members")] +fn members() -> Template { + Template::render("members", context! {}) } - - #[get("/")] fn index() -> Template { @@ -74,11 +83,16 @@ fn post_msg(input: Json>) { return; } +#[get("/services")] +fn services() -> Template { + Template::render("services", context! {}) +} + #[get("/guestbook")] fn guests() -> Template { let guest_json = match read_guest_messages() { Ok(x) => x, - Err(x) => panic!("Error while reading guest messages: {x:?}") + Err(x) => panic!("Error while reading guest messages: {x:?}"), }; Template::render("guest", &guest_json) } @@ -86,13 +100,23 @@ fn guests() -> Template { #[launch] fn rocket() -> _ { if !check_file(GUEST_MESSAGES) { - log(LogLevel::Warn, format!("Guest messages file ({}) has not been found. Creating a new one.", GUEST_MESSAGES).as_str()); + log( + LogLevel::Warn, + format!( + "Guest messages file ({}) has not been found. Creating a new one.", + GUEST_MESSAGES + ) + .as_str(), + ); let mut file = File::create(GUEST_MESSAGES).expect("Failed to create file."); - file.write_all(b"{\"messages\":[]}").expect("Failed to write to file."); + file.write_all(b"{\"messages\":[]}") + .expect("Failed to write to file."); } build() - .mount("/", routes![index, guests, post_msg]) + .mount( + "/", + routes![index, guests, post_msg, members, post, services, abuse], + ) .mount("/assets", FileServer::from(ASSETS_DIR)) .attach(Template::fairing()) } - diff --git a/templates.old/guest.html.tera b/templates.old/guest.html.tera new file mode 100644 index 0000000..5b1c20b --- /dev/null +++ b/templates.old/guest.html.tera @@ -0,0 +1,159 @@ +Guest Book +
+
+

iwakura.rip

+

Leave a nice message for others to read :)

+

Dates are in UTC+2/CEST.

+  [ post message ]  +
+
+ {% for message in messages %} +
+
+ {{ message.name }} + +
+
+

{{ message.body }}

+
+
+ {% endfor %} +
+
+ name +
+
+ message + +
+  [ send ]  +
+
+ + diff --git a/templates.old/index.html.tera b/templates.old/index.html.tera new file mode 100644 index 0000000..2557739 --- /dev/null +++ b/templates.old/index.html.tera @@ -0,0 +1,159 @@ +
+ +
+
+
+ About +

iwakura.rip is a collection of servers hosting mostly-private services for hexlocation & friends.

+

The iwakura.rip website is also connected to dn42 (iwakura.dn42). We are planning to connect our services to dn42 too.

+
+
+ Explanation +

Most of the gifs/art/names/ui design is inspired by/based on Serial Experiments Lain, an anime series about Lain Iwakura

+
+
+ Disclaimer +

Serial Experiments Lain is the property of Triangle Studios. iwakura.rip is not affiliated with Triangle Studios.

+
+
+
+ + diff --git a/templates.old/verify.html.tera b/templates.old/verify.html.tera new file mode 100644 index 0000000..449f689 --- /dev/null +++ b/templates.old/verify.html.tera @@ -0,0 +1,35 @@ + + + + +
+

Make sure to verify our PGP keys when communicating with us.

+ hex + andre +

Please encrypt any messages containing important details towards using our PGP keys. Thank you.

+
+ + + diff --git a/templates/abuse.html.tera b/templates/abuse.html.tera new file mode 100644 index 0000000..bef5c49 --- /dev/null +++ b/templates/abuse.html.tera @@ -0,0 +1,21 @@ +{% extends "base" %} +{% block title %}report abuse{% endblock title %} +{% block content %} +We ask that you report any abuse you find to: abuse@iwakura.rip.
+Please make sure your e-mail contains the following: +
    +
  1. Type of abuse
  2. +
  3. Evidence (no screenshots, hard evidence only)
  4. +
  5. Origin of abuse (e-mail address, IP, domain etc)
  6. +
  7. Additional information that might help us.
  8. +
+ +Please consider the following when sending an abuse e-mail. +
    +
  1. We are *not* able to provide any personal identifiable information, as we do not store them.
  2. +
  3. We take abuse notifications very serious. Sending us multiple false abuse reports will result in a permanent block from our mailserver.
  4. +
  5. We try to respond within 48 hours. Do not flood our inboxes.
  6. +
  7. Please be respectful at all times.
  8. +
+ +{% endblock content %} diff --git a/templates/base.html.tera b/templates/base.html.tera new file mode 100644 index 0000000..63053fa --- /dev/null +++ b/templates/base.html.tera @@ -0,0 +1,22 @@ + + + + {% block title %}{% endblock title %} - iwakura.rip + + + +
+

iwakura.rip


+ + +
+
{% block content %}{% endblock content %}
+
+ + diff --git a/templates/guest.html.tera b/templates/guest.html.tera index bc3a7d7..2014939 100644 --- a/templates/guest.html.tera +++ b/templates/guest.html.tera @@ -1,159 +1,20 @@ -Guest Book -
-
-

iwakura.rip

-

Leave a nice message for others to read :)

-

Dates are in UTC+2/CEST.

-  [ post message ]  -
-
+{% extends "base" %} +{% block title %}guestbook{% endblock title %} +{% block content %} +

post a message?

+
+
{% for message in messages %}
{{ message.name }} - +

{{ message.body }}

+
{% endfor %} -
-
- name -
-
- message - -
-  [ send ]  -
- - +{% endblock content %} diff --git a/templates/index.html.tera b/templates/index.html.tera index 842ff99..71741b5 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -1,158 +1,6 @@ -
- -
-
-
- About -

iwakura.rip is a collection of servers hosting mostly-private services for hexlocation & friends.

-

The iwakura.rip website is also connected to dn42 (iwakura.dn42). We are planning to connect our services to dn42 too.

-
-
- Explanation -

Most of the gifs/art/names/ui design is inspired by/based on Serial Experiments Lain, an anime series about Lain Iwakura

-
-
- Disclaimer -

Serial Experiments Lain is the property of Triangle Studios. iwakura.rip is not affiliated with Triangle Studios.

-
-
-
- - +{% extends "base" %} +{% block title %}homepage{% endblock title %} +{% block content %} +Welcome to iwakura.rip. We are a small group of technology nerds and geeks fascinated by computers and technology.
+We host a bunch of services on this domain for public usage. Want access? Just send me a pgp-encrypted email (hex[a]iwakura.rip) and introduce yourself :) +{% endblock content %} diff --git a/templates/macros.html.tera b/templates/macros.html.tera new file mode 100644 index 0000000..f05e7f3 --- /dev/null +++ b/templates/macros.html.tera @@ -0,0 +1,10 @@ +{% macro service(title, description, href, img, h="16") %} +
+

+ + {{title}} +

+
+

{{description}}

+
+{% endmacro service %} diff --git a/templates/members.html.tera b/templates/members.html.tera new file mode 100644 index 0000000..392cdca --- /dev/null +++ b/templates/members.html.tera @@ -0,0 +1,9 @@ +{% extends "base" %} +{% block title %}members{% endblock title %} +{% block content %} +Make sure to verify our PGP keys when communicating with us. + +{% endblock content %} diff --git a/templates/post.html.tera b/templates/post.html.tera new file mode 100644 index 0000000..4d3a743 --- /dev/null +++ b/templates/post.html.tera @@ -0,0 +1,26 @@ +{% extends "base" %} +{% block title %}post a message{% endblock title %} +{% block content %} +
+ name +
+
+ message + +
+ send! +
+ +{% endblock content %} diff --git a/templates/services.html.tera b/templates/services.html.tera new file mode 100644 index 0000000..384d0fb --- /dev/null +++ b/templates/services.html.tera @@ -0,0 +1,16 @@ +{% import "macros" as macros %} +{% extends "base" %} +{% block title %}services{% endblock title %} +{% block content %} +
+ {{macros::service(title="Forgejo", description="A place for everyone to host their source code!", href="https://git.iwakura.rip", img="https://www.marefa.org/w/images/thumb/0/05/Forgejo_logo.svg/640px-Forgejo_logo.svg.png")}} + {{macros::service(title="Jellyfin", description="For all your media consumption needs.", href="https://media.iwakura.rip", img="/assets/img/jellyfin.png")}} + {{macros::service(title="Woodpecker CI", description="Powerful CI/CD to use together with Forgejo.", href="https://ci.iwakura.rip", img="/assets/img/woodpecker.svg")}} + {{macros::service(title="Jellyseerr", description="Get information about your favorite movies and TV shows, all together in one place.", href="https://request.iwakura.rip", img="/assets/img/jellyseerr.ico")}} + {{macros::service(title="DN42", description="We are currently in the process of connecting all of our services to DN42 - an overlay network using internet technologies.", href="https://iwakura.dn42", img="/assets/img/dn42.png")}} + {{macros::service(title="Authelia", description="Open-source authentication & authorization platform.", href="https://a.iwakura.rip", img="/assets/img/authelia.png")}} + {{macros::service(title="E-mail", description="We are hosting our own e-mail servers on an off-shore hosting provider. Note: all emails are currently being stored in plain text. We recommend using PGP encryption.", href="https://mail.iwakura.rip", img="/assets/img/mail.png")}} +

+Other services can be added on request. We also try to provide space for members wanting to host their own services, though stability is something to think about when asking for this. +

We do not own the copyright for any of the projects mentioned above. All copyright goes to their respective owners.

+{% endblock content %}