Skip to content

Commit

Permalink
WIP #578 #577 # 511
Browse files Browse the repository at this point in the history
  • Loading branch information
joepio committed Feb 4, 2023
1 parent c710fe8 commit 603f84e
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 178 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ See [STATUS.md](server/STATUS.md) to learn more about which features will remain
- Fix initial indexing bug #560
- Fix errors on succesful export / import #565
- Fix envs for store path, change `ATOMIC_STORE_DIR` to `ATOMIC_DATA_DIR` #567
- Refactor static file asset hosting #578
- Meta tags server side #577
- Include JSON-AD in initial response, speed up first render #511

## [v0.34.0] - 2022-10-31

Expand Down
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ features = ["rustls"]
version = "4"

[dependencies.actix-web-static-files]
git = "https://github.com/joepio/actix-web-static-files/"
version = "4"

[dependencies.atomic_lib]
Expand Down
Binary file added server/app_assets/default_social_preview.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
104 changes: 52 additions & 52 deletions server/app_assets/dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion server/app_assets/dist/index.js.map

Large diffs are not rendered by default.

18 changes: 10 additions & 8 deletions server/app_assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<meta content="width=device-width,initial-scale=1" name="viewport">
<title>Atomic Data Browser</title>
<meta content="The easiest way to create, share and model Linked Atomic Data." name="description">
<link href="/app_assets/icon.png" rel="icon" type="image/png">
<link href="/app_assets/apple-touch-icon.png" rel="apple-touch-icon" sizes="180x180">
<link href="/app_assets/favicon-32x32.png" rel="icon" sizes="32x32" type="image/png">
<link href="/app_assets/favicon-16x16.png" rel="icon" sizes="16x16" type="image/png">
<link href="/app_assets/site.webmanifest" rel="manifest">
<link color="#1e43a3" href="/app_assets/safari-pinned-tab.svg" rel="mask-icon">
<link href="/icon.png" rel="icon" type="image/png">
<link href="/apple-touch-icon.png" rel="apple-touch-icon" sizes="180x180">
<link href="/favicon-32x32.png" rel="icon" sizes="32x32" type="image/png">
<link href="/favicon-16x16.png" rel="icon" sizes="16x16" type="image/png">
<link href="/site.webmanifest" rel="manifest">
<link color="#1e43a3" href="/safari-pinned-tab.svg" rel="mask-icon">
<meta content="#ffffff" name="msapplication-TileColor">
<meta content="#ffffff" name="theme-color">
<meta content="yes" name="apple-mobile-web-app-capable">
Expand All @@ -32,7 +32,10 @@
body {
background-color: var(--background-color);
}

</style>
<!-- Meta tags and code added by from Atomic-Server -->
<!-- { inject_html_head } -->
</head>

<body>
Expand Down Expand Up @@ -80,9 +83,8 @@
</defs>
</svg>
</div>
<script src="/app_assets/dist/index.js" type="module"></script>
<script src="/dist/index.js" type="module"></script>
<!-- Server custom script, can be set with -->
<script>{ script }</script>

<!-- Service worker -->
<script>
Expand Down
4 changes: 2 additions & 2 deletions server/app_assets/site.webmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"start_url": "/",
"icons": [
{
"src": "/app_assets/android-chrome-192x192.png",
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/app_assets/android-chrome-512x512.png",
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
Expand Down
132 changes: 128 additions & 4 deletions server/src/handlers/single_page_app.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use std::fmt::Display;
use std::fmt::Formatter;

use crate::{appstate::AppState, errors::AtomicServerResult};
use actix_web::HttpResponse;

Expand All @@ -6,10 +9,21 @@ use actix_web::HttpResponse;
pub async fn single_page(
appstate: actix_web::web::Data<AppState>,
) -> AtomicServerResult<HttpResponse> {
let template = include_str!("../../templates/atomic-data-browser.html");
let body = template
.replace("{ script }", &appstate.config.opts.script)
.replace("{ asset_url }", &appstate.config.opts.asset_url);
let template = include_str!("../../app_assets/index.html");
// TODO Get the agent
// let subject = urls::AGENT;
let subject = "http://localhost:9883/Folder/ltg0aypur9d";
let meta_tags: MetaTags = if let Ok(resource) =
appstate
.store
.get_resource_extended(subject, true, Some(urls::PUBLIC_AGENT))
{
resource.into()
} else {
MetaTags::default()
};

let body = template.replace("<!-- { inject_html_head } -->", &meta_tags.to_string());

let resp = HttpResponse::Ok()
.content_type("text/html")
Expand All @@ -23,3 +37,113 @@ pub async fn single_page(

Ok(resp)
}

use atomic_lib::urls;
use atomic_lib::Resource;
use atomic_lib::Storelike;

/* HTML tags for social media and link previews. Also includes JSON-AD body of the requested resource, if publicly available. */
struct MetaTags {
description: String,
title: String,
image: String,
json: Option<String>,
}

impl From<Resource> for MetaTags {
fn from(r: Resource) -> Self {
let description = if let Ok(d) = r.get(urls::DESCRIPTION) {
d.to_string()
} else {
"Open this resource in your browser to view its contents.".to_string()
};
let title = if let Ok(d) = r.get(urls::NAME) {
d.to_string()
} else {
"Atomic Server".to_string()
};
let image = if let Ok(d) = r.get(urls::DOWNLOAD_URL) {
// TODO: check if thefile is actually an image
d.to_string()
} else {
"/default_social_preview.jpg".to_string()
};
let json = if let Ok(serialized) = r.to_json_ad() {
Some(serialized)
} else {
None
};
Self {
description,
title,
image,
json,
}
}
}

impl Default for MetaTags {
fn default() -> Self {
Self {
description: "Sign in to view this resource".to_string(),
title: "Atomic Server".to_string(),
image: "/default_social_preview.jpg".to_string(),
json: None,
}
}
}

impl Display for MetaTags {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let description = escape_html(&self.description);
let image = &self.image;
let title = escape_html(&self.title);

write!(
f,
"<meta name=\"description\" content=\"{description}\">
<meta property=\"og:title\" content=\"{title}\">
<meta property=\"og:description\" content=\"{description}\">
<meta property=\"og:image\" content=\"{image}\">
<meta property=\"twitter:card\" content=\"summary_large_image\">
<meta property=\"twitter:title\" content=\"{title}\">
<meta property=\"twitter:description\" content=\"{description}\">
<meta property=\"twitter:image\" content=\"{image}\">"
)?;
if let Some(json_unsafe) = &self.json {
let json_base64 = base64::encode(json_unsafe);
write!(
f,
"\n<meta property=\"json-ad-initial\" content=\"{}\">",
json_base64
)?;
};
Ok(())
}
}

fn escape_html(s: &str) -> String {
s.replace('<', "&lt;")
.replace('>', "&gt;")
.replace('&', "&amp;")
.replace('\'', "&#x27;")
.replace('"', "&quot;")
.replace('/', "&#x2F;")
}

#[cfg(test)]
mod test {
use super::MetaTags;

#[test]
// Malicious test: try escaping html and adding script tag
fn evil_meta_tags() {
let html = MetaTags {
description: "\"<script>alert('evil')</script>\"".to_string(),
..Default::default()
}
.to_string();
println!("{}", html);
assert!(!html.contains("<script>"));
}
}
2 changes: 1 addition & 1 deletion server/src/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub fn config_routes(app: &mut actix_web::web::ServiceConfig, config: &Config) {
app.service(web::resource("/ws").to(handlers::web_sockets::web_socket_handler))
// .service(web::resource("/sw.js").to(handlers::service_worker::service_worker))
.service(web::resource("/download/{path:[^{}]+}").to(handlers::download::handle_download))
.service(ResourceFiles::new("/app_assets", generated))
.service(ResourceFiles::new("/", generated).do_use_guard())
// Catch all (non-download) HTML requests and send them to the single page app
.service(
web::resource(ANY)
Expand Down
108 changes: 0 additions & 108 deletions server/templates/atomic-data-browser.html

This file was deleted.

0 comments on commit 603f84e

Please sign in to comment.