From cf3b11862c99ae3808ab64f1777eaa9ff8945814 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Fri, 12 May 2023 14:51:10 +0200 Subject: [PATCH] Got basic index page, started on new domain page --- src/service.rs | 97 +++-- src/service/http_tpl/base.html | 49 +++ src/service/http_tpl/domain_get_new.html | 41 ++ src/service/http_tpl/index.html | 54 ++- src/service/http_tpl/static/concrete.css | 400 ++++++++++++++++++++ src/service/http_tpl/static/new.css | 432 ---------------------- src/service/http_tpl/static/normalize.css | 349 +++++++++++++++++ 7 files changed, 948 insertions(+), 474 deletions(-) create mode 100644 src/service/http_tpl/base.html create mode 100644 src/service/http_tpl/domain_get_new.html create mode 100644 src/service/http_tpl/static/concrete.css delete mode 100644 src/service/http_tpl/static/new.css create mode 100644 src/service/http_tpl/static/normalize.css diff --git a/src/service.rs b/src/service.rs index 6ecc626..482ff37 100644 --- a/src/service.rs +++ b/src/service.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use std::collections::HashMap; use std::error::Error; use std::sync; use warp::Filter; @@ -8,33 +9,55 @@ use crate::domain; pub mod http_tpl; /* - * POST /domain/init (domain, config) -> token - * POST /domain/config (domain, config) + * POST /domain/config (domain, config, secret, init?) -> token? * GET /domain/config (domain) -> config * GET /domains */ type Handlebars<'a> = sync::Arc>; -fn render<'a, T: 'a>(hbs: Handlebars<'a>, name: &'a str, value: &'a T) -> impl warp::Reply +struct RenderContext<'a> { + handlebars: Handlebars<'a>, + query_args: HashMap, +} + +// TODO make this use an io::Write, rather than warp::Reply +fn render<'a, T>(handlebars: Handlebars<'a>, name: &'a str, value: T) -> impl warp::Reply where T: Serialize, { // TODO deal with 404 - let render = hbs - .render(name, value) + let render = handlebars + .render(name, &value) .unwrap_or_else(|err| err.to_string()); let content_type = mime_guess::from_path(name) .first_or_octet_stream() .to_string(); - warp::reply::with_header(warp::reply::html(render), "Content-Type", content_type) + let reply = warp::reply::html(render); + + warp::reply::with_header(reply, "Content-Type", content_type) } -#[derive(Deserialize)] -struct DomainInitRequest { - //config: domain::config::Config, +fn render_page<'a, T>(render_ctx: RenderContext<'a>, name: String, data: T) -> impl warp::Reply +where + T: Serialize, +{ + #[derive(Serialize)] + struct Presenter { + page_name: String, + query_args: HashMap, + data: T, + } + + let presenter = Presenter { + page_name: name, + query_args: render_ctx.query_args, + data, + }; + + render(render_ctx.handlebars, "/base.html", presenter) } pub fn new( @@ -44,25 +67,51 @@ pub fn new( Box, > { let hbs = sync::Arc::new(self::http_tpl::get()?); - let with_hbs = warp::any().map(move || hbs.clone()); - - let index = warp::get() - .and(warp::path::end()) - .and(with_hbs.clone()) - .map(|hbs: Handlebars<'_>| render(hbs, "/index.html", &())); + let with_render_ctx = warp::any() + .and(warp::query::>()) + .map(move |query_args: HashMap| RenderContext { + handlebars: hbs.clone(), + query_args, + }); let static_dir = warp::get() + .and(with_render_ctx.clone()) .and(warp::path("static")) .and(warp::path::full()) - .and(with_hbs.clone()) - .map(|full: warp::path::FullPath, hbs: Handlebars<'_>| render(hbs, full.as_str(), &())); + .map( + |render_ctx: RenderContext<'_>, full: warp::path::FullPath| { + render(render_ctx.handlebars, full.as_str(), ()) + }, + ); - //filter = warp::path!("domain" / "init").and(warp::post()) - // .and(warp::query::()) - // .map(|q: DomainInitRequest| { - // let config_hash = q.config.hash().expect("TODO"); - // warp::reply::html(config_hash) - // }); + let index = warp::get() + .and(with_render_ctx.clone()) + .and(warp::path::end()) + .map(|render_ctx: RenderContext<'_>| { + render_page(render_ctx, String::from("/index.html"), ()) + }); - Ok(index.or(static_dir)) + #[derive(Deserialize)] + struct DomainGetNewRequest { + domain: String, + } + + let domain_get = warp::get() + .and(with_render_ctx.clone()) + .and(warp::path("domain.html")) + .and(warp::query::()) + .map(|render_ctx: RenderContext<'_>, req: DomainGetNewRequest| { + #[derive(Serialize)] + struct DomainGetNewResponse { + domain: String, + } + + render_page( + render_ctx, + String::from("/domain_get_new.html"), + DomainGetNewResponse { domain: req.domain }, + ) + }); + + Ok(static_dir.or(index).or(domain_get)) } diff --git a/src/service/http_tpl/base.html b/src/service/http_tpl/base.html new file mode 100644 index 0000000..cd0beab --- /dev/null +++ b/src/service/http_tpl/base.html @@ -0,0 +1,49 @@ + + + + + + + + + Cosmux - The universal, zero-authentication hosting service + + + + + + + + + + + + + + + +
+ +
+

Cosmux

+
The universal, zero-authentication hosting service
+
+ +
+ {{> (lookup this "page_name")}} +
+ +
+ + + + diff --git a/src/service/http_tpl/domain_get_new.html b/src/service/http_tpl/domain_get_new.html new file mode 100644 index 0000000..024676e --- /dev/null +++ b/src/service/http_tpl/domain_get_new.html @@ -0,0 +1,41 @@ +

+ Configure New Domain +

+ +

Your domain {{ data.domain }} is not yet configured with Cosmux. +To get started, please input the details of a public git repo which will be used +to serve your domain. When you update the given branch, your domain will be +automatically updated too!

+ +

In the future Cosmux will support more backends than just git + repos.

+ + +
+ + + +
+ Git Repository +

+ +

+ +

+ +

+
+ +
diff --git a/src/service/http_tpl/index.html b/src/service/http_tpl/index.html index cfc58e2..b54ac2e 100644 --- a/src/service/http_tpl/index.html +++ b/src/service/http_tpl/index.html @@ -1,29 +1,47 @@ - +

Cosmux connects your domain to whatever you want to host on it, all with no +account needed. Just input your desired backend, add two entries to your DNS +server, and you're done!

- +

Cosmux is currently only a proof-of-concept with limited features, + but will continue to be expanded as development time permits

- +

The following backends are supported for serving a domain:

- +
    +
  • Git repository: Your domain will be served out of a + branch of a public git repository, a la Github Pages.
  • +
  • IPFS/IPNS Hash: TODO
  • +
  • Alternative URL (reverse proxy): TODO
  • +
  • Google Drive: TODO (maybe)
  • +
  • Dropbox: TODO (maybe)
  • +
- Hello, world! +

Get Started

- +

Input your domain name below to set it up, or reconfigure it if you have used +it before:

- +
+ - + +
- +

Alternatively you can do any of the following alternative actions:

- +
    +
  • List all existing domains
  • +
  • View the Source Code (TODO)
  • +
  • View the Project Roadmap (TODO)
  • +
  • Report a Bug (TODO)
  • +
-

OK

- - - - +

About

+

Cosmux is an open-source project which is designed to be hosted by +individuals for their community of friends and family. By making it super easy +to set up a domain we can help our non-technical folk own their own slice of +the internet, the way it was always intended.

diff --git a/src/service/http_tpl/static/concrete.css b/src/service/http_tpl/static/concrete.css new file mode 100644 index 0000000..9159d09 --- /dev/null +++ b/src/service/http_tpl/static/concrete.css @@ -0,0 +1,400 @@ +/*! concrete.css v2.0.3 | MIT License | github.com/louismerlin/concrete.css */ + +/** + * 1. Modify the base font-size to 62.5% so that 1.6rem = 16px. + * 2. Set box-sizing globally to handle padding and border widths. + */ + +html { + font-size: 62.5%; /* 1 */ + box-sizing: border-box; /* 2 */ +} + +/** + * 1. Continue the global box-sizing modification. + * 2. Set the underline size for all elements. + */ + +*, ::after, ::before { + box-sizing: inherit; /* 1 */ + text-decoration-thickness: .2rem; /* 2 */ +} + +/** + * 1. Set global font size to 2rem (20px) with a normal weight. + * 2. Set the text and background color to white and black by default. + * 3. Set the font-family to Helvetica, or equivalent. + */ + +body { + font-size: 2rem; /* 1 */ + font-weight: 400; /* 1 */ + background: #fff; /* 2 */ + color: #111; /* 2 */ + font-family: Helvetica, Arial, sans-serif; /* 3 */ +} + +/** + * Set the link color to black + */ + +a { + color: #111; +} + +/** + * 1. Set the max width of images to 100%, so that they don't overflow. + * 2. Set the height of images relative to their width. + */ + +img { + max-width: 100%; /* 1 */ + height: auto; /* 2 */ +} + +/** + * 1. Center the main element horizontally. + * 2. Set the width of the element to 640px, with padding for mobile screens. + */ + +main { + margin: auto; /* 1 */ + max-width: 66rem; /* 2 */ + padding: 0 1rem; /* 2 */ + width: 100%; /* 2 */ +} + +/** + * 1. Add some padding around the header. + * 2. Increase the size of text in the header. + */ + +header { + padding: 16rem 0; /* 1 */ + font-size: 1.2em; /* 2 */ +} + +/** + * Center the text in the footer. + */ + +footer { + text-align: center; +} + +/** + * Add some padding around the sections. + */ + +section { + padding: 4rem 0; +} + +/** + * 1. Change the style of the button. + * 2. Set the color and border of the button. + * 3. Add the pointer cursor when hovering a button. + */ + +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + display: inline-block; /* 1 */ + vertical-align: middle; /* 1 */ + padding: .4rem 1rem; /* 1 */ + font-size: 2rem; /* 1 */ + font-weight: normal; /* 1 */ + margin-bottom: 1rem; /* 1 */ + background: #fff; /* 2 */ + color: #111; /* 2 */ + border: .2rem solid #111; /* 2 */ + border-radius: 0; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * 1. Invert the colors of the disabled button. + * 2. Add the not-allowed cursor when hovering a disabled button. + */ + +button:disabled, +input[type="button"]:disabled, +input[type="reset"]:disabled, +input[type="submit"]:disabled{ + color: #fff; /* 1 */ + background: #111; /* 1 */ + cursor: not-allowed; /* 2 */ +} + +/** + * Set the list bullet to square. + */ + +ul { + list-style: square; +} + +/** + * Set the border around a fieldset. + */ + +fieldset { + border: .2rem solid #111; +} + +/** + * 1. Modify the display of labels and legends. + * 2. Add a margin underneath. + */ + +label, legend { + display: block; /* 1 */ + font-weight: bold; /* 1 */ + margin-bottom: .8rem; /* 2 */ +} + +/** + * 1. Change the appearance of the text input. + * 2. Set the color and border of the text input. + */ + +input[type="email"], +input[type="number"], +input[type="password"], +input[type="search"], +input[type="tel"], +input[type="text"], +input[type="url"], +textarea, +select { + -webkit-appearance: none; /* 1 */ + -moz-appearance: none; /* 1 */ + appearance: none; /* 1 */ + box-shadow: none; /* 1 */ + box-sizing: inherit; /* 1 */ + padding: .4rem 1rem; /* 1 */ + width: 100%; /* 1 */ + font-size: 2rem; /* 1 */ + color: #111; /* 2 */ + background-color: #fff; /* 2 */ + border: .2rem solid #111; /* 2 */ + border-radius: 0; /* 2 */ +} + +/** + * Set margin for form elements. + */ + +fieldset, input, select, textarea { + margin: 0 0 1.6rem 0; +} + +/** + * 1. Set the font color for the placeholder in inputs. + * 2. Set font-style to italic for the placeholder in inputs. + */ + +input::placeholder, +textarea::placeholder { + color: #111; /* 1 */ + font-style: italic; /* 2 */ +} + +/** + * 1. Expand width to 100% for the table element. + * 2. Remove the distance between the borders of adjacent table cells. + */ + +table { + width: 100%; /* 1 */ + border-spacing: 0; /* 2 */ +} + +/** + * Add padding around table cells. + */ + +td, th { + padding: .8rem; +} + +/** + * Remove left padding for first cell in a row. + */ + +td:first-child, th:first-child { + padding-left: 0; +} + +/** + * Remove right padding for last cell in a row. + */ + +td:last-child, th:last-child { + padding-right: 0; +} + +/** + * 1. Add a border under the table header. + * 2. Align the text to the left in the table header. + */ + +th { + border-bottom: .2rem solid #111; /* 1 */ + text-align: left; /* 2 */ +} + +/** + * Add a thiner border under table rows. + */ + +td { + border-bottom: .1rem solid #111; +} + +/** + * 1. Change the margins and padding. + * 2. Add a border on the left of these elements. + * 3. Set the y overflow to hidden to hide the navigation bar. + */ + +blockquote, pre { + margin-left: 0; /* 1 */ + margin-right: 0; /* 1 */ + padding: 1rem 1.6rem; /* 1 */ + border-left: .2rem solid #111; /* 2 */ + overflow-y: hidden; /* 3 */ +} + +/** + * 1. Set the rest of the border of the preformatted element to dotted. + * 2. Re-set the left border style. + */ + +pre { + border: 0.1rem dotted #111; + border-left: 0.2rem solid #111; +} + +/** + * 1. Modify the display of the code block. + * 2. Reduce the font size of the code block. + */ + +pre > code { + white-space: pre; /* 1 */ + display: block; /* 1 */ + font-size: 1.6rem; /* 2 */ +} + +/** + * 1. Modify the display of the progress bar in all browsers. + * 2. Set the colors and border of the progress bar. + */ + +progress { + -moz-appearance: none; /* 1 */ + -webkit-appearance: none; /* 1 */ + display: block; /* 1 */ + height: 1rem; /* 1 */ + overflow: hidden; /* 1 */ + padding: 0; /* 1 */ + width: 100%; /* 1 */ + background: #fff; /* 2 */ + color: #111; /* 2 */ + border: .2rem solid #111; /* 2 */ + border-radius: 0; /* 2 */ +} + +/** + * Set the background color of the webkit progress bar. + */ + +progress::-webkit-progress-bar { + background-color: #fff; +} + +/** + * Set the color of the webkit progress bar. + */ + +progress::-webkit-progress-value { + background-color: #111; +} + +/** + * Set the color of the mozilla progress bar. + */ + +progress::-moz-progress-bar { + background-color: #111; +} + +/** + * Set the border for the horizontal rule. + */ + +hr { + border: .1rem solid #111; +} + +/** + * Invert the colors if the user has dark mode activated. + */ + +@media (prefers-color-scheme: dark) { + body { + background: #111; + color: #fff; + } + a, + input::placeholder, + textarea::placeholder { + color: #fff; + } + button, + input[type="button"], + input[type="reset"], + input[type="submit"], + input[type="email"], + input[type="number"], + input[type="password"], + input[type="search"], + input[type="tel"], + input[type="text"], + input[type="url"], + textarea, + select, + progress { + background: #111; + color: #fff; + border-color: #fff; + } + button:disabled, + input[type="button"]:disabled, + input[type="reset"]:disabled, + input[type="submit"]:disabled{ + color: #111; + background: #fff; + } + fieldset { + border-color: #fff; + } + td, + th, + blockquote, + pre, + hr { + border-color: #fff; + } + progress::-webkit-progress-bar { + background-color: #111; + } + progress::-webkit-progress-value { + background-color: #fff; + } + progress::-moz-progress-bar { + background-color: #fff; + } +} diff --git a/src/service/http_tpl/static/new.css b/src/service/http_tpl/static/new.css deleted file mode 100644 index d253661..0000000 --- a/src/service/http_tpl/static/new.css +++ /dev/null @@ -1,432 +0,0 @@ -:root { - --nc-font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - --nc-font-mono: Consolas, monaco, 'Ubuntu Mono', 'Liberation Mono', 'Courier New', Courier, monospace; - --nc-tx-1: #000000; - --nc-tx-2: #1A1A1A; - --nc-bg-1: #FFFFFF; - --nc-bg-2: #F6F8FA; - --nc-bg-3: #E5E7EB; - --nc-lk-1: #0070F3; - --nc-lk-2: #0366D6; - --nc-lk-tx: #FFFFFF; - --nc-ac-1: #79FFE1; - --nc-ac-tx: #0C4047; -} - -@media (prefers-color-scheme: dark) { - :root { - --nc-tx-1: #ffffff; - --nc-tx-2: #eeeeee; - --nc-bg-1: #000000; - --nc-bg-2: #111111; - --nc-bg-3: #222222; - --nc-lk-1: #3291FF; - --nc-lk-2: #0070F3; - --nc-lk-tx: #FFFFFF; - --nc-ac-1: #7928CA; - --nc-ac-tx: #FFFFFF; - } -} - -* { - /* Reset margins and padding */ - margin: 0; - padding: 0; -} - -address, -area, -article, -aside, -audio, -blockquote, -datalist, -details, -dl, -fieldset, -figure, -form, -input, -iframe, -img, -meter, -nav, -ol, -optgroup, -option, -output, -p, -pre, -progress, -ruby, -section, -table, -textarea, -ul, -video { - /* Margins for most elements */ - margin-bottom: 1rem; -} - -html,input,select,button { - /* Set body font family and some finicky elements */ - font-family: var(--nc-font-sans); -} - -body { - /* Center body in page */ - margin: 0 auto; - max-width: 750px; - padding: 2rem; - border-radius: 6px; - overflow-x: hidden; - word-break: break-word; - overflow-wrap: break-word; - background: var(--nc-bg-1); - - /* Main body text */ - color: var(--nc-tx-2); - font-size: 1.03rem; - line-height: 1.5; -} - -::selection { - /* Set background color for selected text */ - background: var(--nc-ac-1); - color: var(--nc-ac-tx); -} - -h1,h2,h3,h4,h5,h6 { - line-height: 1; - color: var(--nc-tx-1); - padding-top: .875rem; -} - -h1, -h2, -h3 { - color: var(--nc-tx-1); - padding-bottom: 2px; - margin-bottom: 8px; - border-bottom: 1px solid var(--nc-bg-2); -} - -h4, -h5, -h6 { - margin-bottom: .3rem; -} - -h1 { - font-size: 2.25rem; -} - -h2 { - font-size: 1.85rem; -} - -h3 { - font-size: 1.55rem; -} - -h4 { - font-size: 1.25rem; -} - -h5 { - font-size: 1rem; -} - -h6 { - font-size: .875rem; -} - -a { - color: var(--nc-lk-1); -} - -a:hover { - color: var(--nc-lk-2); -} - -abbr:hover { - /* Set the '?' cursor while hovering an abbreviation */ - cursor: help; -} - -blockquote { - padding: 1.5rem; - background: var(--nc-bg-2); - border-left: 5px solid var(--nc-bg-3); -} - -abbr { - cursor: help; -} - -blockquote *:last-child { - padding-bottom: 0; - margin-bottom: 0; -} - -header { - background: var(--nc-bg-2); - border-bottom: 1px solid var(--nc-bg-3); - padding: 2rem 1.5rem; - - /* This sets the right and left margins to cancel out the body's margins. It's width is still the same, but the background stretches across the page's width. */ - - margin: -2rem calc(0px - (50vw - 50%)) 2rem; - - /* Shorthand for: - - margin-top: -2rem; - margin-bottom: 2rem; - - margin-left: calc(0px - (50vw - 50%)); - margin-right: calc(0px - (50vw - 50%)); */ - - padding-left: calc(50vw - 50%); - padding-right: calc(50vw - 50%); -} - -header h1, -header h2, -header h3 { - padding-bottom: 0; - border-bottom: 0; -} - -header > *:first-child { - margin-top: 0; - padding-top: 0; -} - -header > *:last-child { - margin-bottom: 0; -} - -a button, -button, -input[type="submit"], -input[type="reset"], -input[type="button"] { - font-size: 1rem; - display: inline-block; - padding: 6px 12px; - text-align: center; - text-decoration: none; - white-space: nowrap; - background: var(--nc-lk-1); - color: var(--nc-lk-tx); - border: 0; - border-radius: 4px; - box-sizing: border-box; - cursor: pointer; - color: var(--nc-lk-tx); -} - -a button[disabled], -button[disabled], -input[type="submit"][disabled], -input[type="reset"][disabled], -input[type="button"][disabled] { - cursor: default; - opacity: .5; - - /* Set the [X] cursor while hovering a disabled link */ - cursor: not-allowed; -} - -.button:focus, -.button:hover, -button:focus, -button:hover, -input[type="submit"]:focus, -input[type="submit"]:hover, -input[type="reset"]:focus, -input[type="reset"]:hover, -input[type="button"]:focus, -input[type="button"]:hover { - background: var(--nc-lk-2); -} - -code, -pre, -kbd, -samp { - /* Set the font family for monospaced elements */ - font-family: var(--nc-font-mono); -} - -code, -samp, -kbd, -pre { - /* The main preformatted style. This is changed slightly across different cases. */ - background: var(--nc-bg-2); - border: 1px solid var(--nc-bg-3); - border-radius: 4px; - padding: 3px 6px; - font-size: 0.9rem; -} - -kbd { - /* Makes the kbd element look like a keyboard key */ - border-bottom: 3px solid var(--nc-bg-3); -} - -pre { - padding: 1rem 1.4rem; - max-width: 100%; - overflow: auto; -} - -pre code { - /* When is in a
, reset it's formatting to blend in */
-	background: inherit;
-	font-size: inherit;
-	color: inherit;
-	border: 0;
-	padding: 0;
-	margin: 0;
-}
-
-code pre {
-	/* When 
 is in a , reset it's formatting to blend in */
-	display: inline;
-	background: inherit;
-	font-size: inherit;
-	color: inherit;
-	border: 0;
-	padding: 0;
-	margin: 0;
-}
-
-details {
-	/* Make the 
look more "clickable" */ - padding: .6rem 1rem; - background: var(--nc-bg-2); - border: 1px solid var(--nc-bg-3); - border-radius: 4px; -} - -summary { - /* Makes the look more like a "clickable" link with the pointer cursor */ - cursor: pointer; - font-weight: bold; -} - -details[open] { - /* Adjust the
padding while open */ - padding-bottom: .75rem; -} - -details[open] summary { - /* Adjust the
padding while open */ - margin-bottom: 6px; -} - -details[open]>*:last-child { - /* Resets the bottom margin of the last element in the
while
is opened. This prevents double margins/paddings. */ - margin-bottom: 0; -} - -dt { - font-weight: bold; -} - -dd::before { - /* Add an arrow to data table definitions */ - content: '→ '; -} - -hr { - /* Reset the border of the
separator, then set a better line */ - border: 0; - border-bottom: 1px solid var(--nc-bg-3); - margin: 1rem auto; -} - -fieldset { - margin-top: 1rem; - padding: 2rem; - border: 1px solid var(--nc-bg-3); - border-radius: 4px; -} - -legend { - padding: auto .5rem; -} - -table { - /* border-collapse sets the table's elements to share borders, rather than floating as separate "boxes". */ - border-collapse: collapse; - width: 100% -} - -td, -th { - border: 1px solid var(--nc-bg-3); - text-align: left; - padding: .5rem; -} - -th { - background: var(--nc-bg-2); -} - -tr:nth-child(even) { - /* Set every other cell slightly darker. Improves readability. */ - background: var(--nc-bg-2); -} - -table caption { - font-weight: bold; - margin-bottom: .5rem; -} - -textarea { - /* Don't let the