diff options
-rw-r--r-- | public/404.html | 15 | ||||
-rw-r--r-- | public/admin.html | 15 | ||||
-rw-r--r-- | public/css/main.css | 8 | ||||
-rw-r--r-- | public/home.html | 15 | ||||
-rw-r--r-- | public/js/components.js | 37 | ||||
-rw-r--r-- | public/js/home.js | 6 | ||||
-rw-r--r-- | public/js/main.js | 11 | ||||
-rw-r--r-- | public/js/people.js | 4 | ||||
-rw-r--r-- | public/login.html | 17 | ||||
-rw-r--r-- | public/people.html | 15 | ||||
-rw-r--r-- | public/profile.html | 16 | ||||
-rw-r--r-- | public/robots.txt | 9 | ||||
-rw-r--r-- | src/public/file.rs | 4 | ||||
-rw-r--r-- | src/public/mod.rs | 3 | ||||
-rw-r--r-- | src/public/pages.rs | 15 | ||||
-rw-r--r-- | src/types/extract.rs | 26 |
16 files changed, 179 insertions, 37 deletions
diff --git a/public/404.html b/public/404.html index c89d93d..4a382c0 100644 --- a/public/404.html +++ b/public/404.html @@ -2,11 +2,22 @@ <html lang="en"> <head> <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>XSSBook - Not Found</title> + + <meta name="author" content="Tyler Murphy"> + <meta name="description" content="404 Page"> + + <meta property="og:title" content="xssbook"> + <meta property="og:site_name" content="xssbook.com"> + <meta property="og:description" content="404 Page"> + + <meta itemprop="name" content="xssbook"> + <meta itemprop="description" content="404 Page"> + <link rel="stylesheet" href="/css/main.css"> <link rel="stylesheet" href="/css/404.css"> <link rel="stylesheet" href="/css/header.css"> - <script src="/js/main.js"></script> - <title>XSSBook - Not Found</title> </head> <body> <div id="header"> diff --git a/public/admin.html b/public/admin.html index 2d2bcd6..cb68302 100644 --- a/public/admin.html +++ b/public/admin.html @@ -2,11 +2,22 @@ <html lang="en"> <head> <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>XSSBook - Admin Panel</title> + + <meta name="author" content="Tyler Murphy"> + <meta name="description" content="Admin Panel"> + + <meta property="og:title" content="xssbook"> + <meta property="og:site_name" content="xssbook.com"> + <meta property="og:description" content="Admin Panel"> + + <meta itemprop="name" content="xssbook"> + <meta itemprop="description" content="Admin Panel"> + <link rel="stylesheet" href="/css/main.css"> <link rel="stylesheet" href="/css/header.css"> <link rel="stylesheet" href="/css/admin.css"> - <script src="/js/admin.js" type="module"></script> - <title>XSSBook - Admin Panel</title> </head> <body> <div id="header"> diff --git a/public/css/main.css b/public/css/main.css index 4819f38..d5ac0bf 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -28,16 +28,19 @@ body { @font-face { font-family: facebook; src: url("../fonts/facebook.otf") format("opentype"); + font-display: swap; } @font-face { font-family: sfpro; src: url("../fonts/sfpro.otf") format("opentype"); + font-display: swap; } @font-face { font-family: sfprobold; src: url("../fonts/sfprobold.otf") format("opentype"); + font-display: swap; } .logo { @@ -322,14 +325,15 @@ form { width: 100%; } -#load { +#load, .cload { width: 100%; display: flex; justify-content: center; padding-bottom: 20px; + cursor: pointer; } -#load a:hover { +#load span:hover, .cload span:hover { border-bottom: var(--medium) 1px solid; } diff --git a/public/home.html b/public/home.html index 5cc7776..6ba4a5a 100644 --- a/public/home.html +++ b/public/home.html @@ -2,10 +2,23 @@ <html lang="en"> <head> <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>XSSBook - Home</title> + + <meta name="author" content="Tyler Murphy"> + <meta name="description" content="Home"> + + <meta property="og:title" content="xssbook"> + <meta property="og:site_name" content="xssbook.com"> + <meta property="og:description" content="Home"> + + <meta itemprop="name" content="xssbook"> + <meta itemprop="description" content="Home"> + <link rel="stylesheet" href="/css/main.css"> <link rel="stylesheet" href="/css/header.css"> <link rel="stylesheet" href="/css/home.css"> - <title>XSSBook - Home</title> + <script type="module" src="/js/home.js"></script> </head> <body> diff --git a/public/js/components.js b/public/js/components.js index 9816457..7e2a268 100644 --- a/public/js/components.js +++ b/public/js/components.js @@ -7,23 +7,23 @@ export function header(home, people, user_id) { return [ div({id: 'header'}, span({class: 'logo'}, - a({href: '/'}, + a({href: '/', 'aria-label': 'xssbook.com'}, parse('xssbook') ) ), div({class: 'buttons'}, - a({id: 'home', class: home ? 'selected' : '', href: 'home'}, + a({id: 'home', class: home ? 'selected' : '', href: '/home', 'aria-label': 'xssbook home page'}, svg({viewBox: '0 0 28 28', fill: 'currentColor', height: '28', width: '28'}, path({d: "M25.825 12.29C25.824 12.289 25.823 12.288 25.821 12.286L15.027 2.937C14.752 2.675 14.392 2.527 13.989 2.521 13.608 2.527 13.248 2.675 13.001 2.912L2.175 12.29C1.756 12.658 1.629 13.245 1.868 13.759 2.079 14.215 2.567 14.479 3.069 14.479L5 14.479 5 23.729C5 24.695 5.784 25.479 6.75 25.479L11 25.479C11.552 25.479 12 25.031 12 24.479L12 18.309C12 18.126 12.148 17.979 12.33 17.979L15.67 17.979C15.852 17.979 16 18.126 16 18.309L16 24.479C16 25.031 16.448 25.479 17 25.479L21.25 25.479C22.217 25.479 23 24.695 23 23.729L23 14.479 24.931 14.479C25.433 14.479 25.921 14.215 26.132 13.759 26.371 13.245 26.244 12.658 25.825 12.29"}) ) ), - a({id: 'people', class: people ? 'selected' : '', href: 'people'}, + a({id: 'people', class: people ? 'selected' : '', href: '/people', 'aria-label': 'xssbook people page'}, svg({viewBox: '0 0 28 28', fill: 'currentColor', height: '28', width: '28'}, path({d: "M10.5 4.5c-2.272 0-2.75 1.768-2.75 3.25C7.75 9.542 8.983 11 10.5 11s2.75-1.458 2.75-3.25c0-1.482-.478-3.25-2.75-3.25zm0 8c-2.344 0-4.25-2.131-4.25-4.75C6.25 4.776 7.839 3 10.5 3s4.25 1.776 4.25 4.75c0 2.619-1.906 4.75-4.25 4.75zm9.5-6c-1.41 0-2.125.841-2.125 2.5 0 1.378.953 2.5 2.125 2.5 1.172 0 2.125-1.122 2.125-2.5 0-1.659-.715-2.5-2.125-2.5zm0 6.5c-1.999 0-3.625-1.794-3.625-4 0-2.467 1.389-4 3.625-4 2.236 0 3.625 1.533 3.625 4 0 2.206-1.626 4-3.625 4zm4.622 8a.887.887 0 00.878-.894c0-2.54-2.043-4.606-4.555-4.606h-1.86c-.643 0-1.265.148-1.844.413a6.226 6.226 0 011.76 4.336V21h5.621zm-7.122.562v-1.313a4.755 4.755 0 00-4.749-4.749H8.25A4.755 4.755 0 003.5 20.249v1.313c0 .518.421.938.937.938h12.125c.517 0 .938-.42.938-.938zM20.945 14C24.285 14 27 16.739 27 20.106a2.388 2.388 0 01-2.378 2.394h-5.81a2.44 2.44 0 01-2.25 1.5H4.437A2.44 2.44 0 012 21.562v-1.313A6.256 6.256 0 018.25 14h4.501a6.2 6.2 0 013.218.902A5.932 5.932 0 0119.084 14h1.861z"}) ) ) ), - a({class: 'pfp', id: 'profile', href: 'profile'}, + a({class: 'pfp', id: 'profile', href: '/profile', 'aria-label': 'your xssbook profile'}, user_id === undefined ? parse('') : pfp(user_id) ) ), @@ -49,7 +49,7 @@ export function parsePost(post, users, self) { return ( div({class: 'post', postid: post.post_id}, div({class: 'postheader'}, - a({class: 'pfp', href: `/profile?id=${author.user_id}`}, + a({class: 'pfp', href: `/profile?id=${author.user_id}`, 'aria-label': 'Post author profile like'}, pfp(author.user_id) ), div({class: 'postname'}, @@ -110,7 +110,18 @@ export function parsePost(post, users, self) { parse('Like') ) ), - span({onclick: () => this.parentElement.parentElement.getElementsByClassName('newcomment')[0].focus()}, + span({onclick: (event) => { + + var post = event.target; + while(post.parentElement) { + post = post.parentElement + if (post.getAttribute('postid')) { + break; + } + } + + post.getElementsByClassName('comments')[0].getElementsByClassName('newcomment')[0].focus() + }}, i({class: 'icons comm'}), span({class: 'bold'}, parse('Comment') @@ -122,8 +133,8 @@ export function parsePost(post, users, self) { div({class: 'comment commentsubmit', style: 'margin-top: 0'}), ...comments, comments.length > 0 ? - div({id: 'load', class: 'load', style: 'justify-content: inherit; margin-left: 3.5em; font-size: .9em; margin-bottom: -.5em;'}, - a({class: 'blod gtext', onclick: async (event) => { + div({class: 'cload', style: 'justify-content: inherit; margin-left: 3.5em; font-size: .9em; margin-bottom: -.5em;'}, + span({class: 'blod gtext', onclick: async (event) => { page++; @@ -148,7 +159,7 @@ export function parsePost(post, users, self) { ) : parse(''), div({class: 'comment commentsubmit'}, - a({class: 'pfp', href: 'profile'}, + a({class: 'pfp', href: '/profile', 'aria-label': 'Your profile link'}, pfp(self.user_id) ), form({onsubmit: async (event) => { @@ -173,7 +184,7 @@ export function parsePost(post, users, self) { let comments = post.getElementsByClassName('comments')[0] - let load = comments.getElementsByClassName('load')[0]; + let load = comments.getElementsByClassName('cload')[0]; if (load == undefined) { load = comments.lastChild } @@ -186,7 +197,7 @@ export function parsePost(post, users, self) { event.target.elements.text.value = '' }}, - input({type: 'text', name: 'text', placeholder: 'Write a comment', id: 'newcomment', class: 'newcomment'}) + input({type: 'text', name: 'text', placeholder: 'Write a comment', class: 'newcomment'}) ) ) ) @@ -202,7 +213,7 @@ export function parseComment(comment, users) { return ( div({class: 'comment'}, - a({class: 'pfp'}, + a({class: 'pfp', href: `/profile?id=${comment.user_id}`, 'aria-label': 'Comment author profile link'}, pfp(comment.user_id) ), span({}, @@ -223,7 +234,7 @@ export function parseComment(comment, users) { export function parseUser(user) { return ( - a({class: 'person', href: `/profile?id=${user.user_id}`}, + a({class: 'person', href: `/profile?id=${user.user_id}`, 'aria-label': 'User profile link'}, div({class: 'profile'}, pfp(user.user_id) ), diff --git a/public/js/home.js b/public/js/home.js index edc6823..447f602 100644 --- a/public/js/home.js +++ b/public/js/home.js @@ -34,7 +34,7 @@ function render() { ...header(true, false, data.self.user_id), div({id: 'create'}, div({class: 'create'}, - a({class: 'pfp', href: 'profile'}, + a({class: 'pfp', href: '/profile'}, pfp(data.self.user_id) ), button({class: 'pfp'}, @@ -55,7 +55,7 @@ function render() { ), div({class: 'fullline'}), div({class: 'postheader'}, - a({class: 'pfp', style: 'cursor: auto'}, + a({class: 'pfp', style: 'cursor: auto', href: '/profile'}, pfp(data.self.user_id) ), div({class: 'postname'}, @@ -75,7 +75,7 @@ function render() { ) ), div({id: 'load'}, - a({class: 'blod gtext', onclick: async () => { + span({class: 'blod gtext', onclick: async () => { const posts = await load() data.posts.push(... posts) diff --git a/public/js/main.js b/public/js/main.js index 3ad36b0..b49474c 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -65,8 +65,9 @@ export function form(attrs, ...children) { return createElement("form", attrs, ...children) } -export function img(attrs, ...children) { +export function img(alt, attrs, ...children) { attrs['onerror'] = (event) => event.target.remove() + attrs['alt'] = alt return createElement("img", attrs, ...children) } @@ -98,12 +99,16 @@ export function parse(html) { return document.createRange().createContextualFragment(html); } +export function pfpl(id) { + +} + export function pfp(id) { - return img({src: `/image/avatar?user_id=${id}`}) + return img('pfp', {src: `/image/avatar?user_id=${id}`}) } export function banner(id) { - return img({src: `/image/banner?user_id=${id}`}) + return img('banner', {src: `/image/banner?user_id=${id}`}) } const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', diff --git a/public/js/people.js b/public/js/people.js index 9b7ba46..0a97e93 100644 --- a/public/js/people.js +++ b/public/js/people.js @@ -1,4 +1,4 @@ -import { div, body, a, parse } from './main.js' +import { div, body, span, parse } from './main.js' import { loadself, loaduserspage } from './api.js' import { header, parseUser } from './components.js' @@ -11,7 +11,7 @@ function render() { ...data.users.map(u => parseUser(u)) ), div({id: 'load'}, - a({class: 'bold gtext', onclick: async () => { + span({class: 'bold gtext', onclick: async () => { let users = await load() let el = document.getElementById("users") diff --git a/public/login.html b/public/login.html index ce4d0ff..837a80a 100644 --- a/public/login.html +++ b/public/login.html @@ -2,10 +2,23 @@ <html lang="en"> <head> <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>XSSBook - Login</title> + + <meta name="author" content="Tyler Murphy"> + <meta name="description" content="Login"> + + <meta property="og:title" content="xssbook"> + <meta property="og:site_name" content="xssbook.com"> + <meta property="og:description" content="Login"> + + <meta itemprop="name" content="xssbook"> + <meta itemprop="description" content="Login"> + <link rel="stylesheet" href="/css/main.css"> <link rel="stylesheet" href="/css/login.css"> + <script src="/js/login.js" type="module"></script> - <title>XSSBook - Login</title> </head> <body> <div class="login"> @@ -18,7 +31,7 @@ <input type="password" name="pass" id="pass" placeholder="Password"> <span class="error ctext"></span> <button class="primary login-button bold" value="1" name="login" type="submit" id="login" onclick="window.onlogin()">Log In</button> - <a class="btext ctext">Forgot Password?</a> + <a class="btext ctext" href="/forgot">Forgot Password?</a> <div class="line"></div> <button class="success newacc" onclick="document.getElementById('popup').classList.remove('hidden')">Create new account</button> </div> diff --git a/public/people.html b/public/people.html index 0a7775a..cdbeac3 100644 --- a/public/people.html +++ b/public/people.html @@ -2,11 +2,24 @@ <html lang="en"> <head> <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>XSSBook - People</title> + + <meta name="author" content="Tyler Murphy"> + <meta name="description" content="People"> + + <meta property="og:title" content="xssbook"> + <meta property="og:site_name" content="xssbook.com"> + <meta property="og:description" content="People"> + + <meta itemprop="name" content="xssbook"> + <meta itemprop="description" content="People"> + <link rel="stylesheet" href="/css/main.css"> <link rel="stylesheet" href="/css/header.css"> <link rel="stylesheet" href="/css/people.css"> + <script src="/js/people.js" type="module"></script> - <title>XSSBook - People</title> </head> <body> </body> diff --git a/public/profile.html b/public/profile.html index 893ef3f..35debf8 100644 --- a/public/profile.html +++ b/public/profile.html @@ -1,13 +1,27 @@ <!DOCTYPE html> +<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>XSSBook - Profile</title> + + <meta name="author" content="Tyler Murphy"> + <meta name="description" content="Profile"> + + <meta property="og:title" content="xssbook"> + <meta property="og:site_name" content="xssbook.com"> + <meta property="og:description" content="Profile"> + + <meta itemprop="name" content="xssbook"> + <meta itemprop="description" content="Profile"> + <link rel="stylesheet" href="/css/main.css"> <link rel="stylesheet" href="/css/header.css"> <link rel="stylesheet" href="/css/profile.css"> <link rel="stylesheet" href="/css/home.css"> + <script src="/js/profile.js" type="module"></script> - <title>XSSBook - Profile</title> </head> <body> </body> diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..b1b4ec3 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,9 @@ +User-agent: Googlebot +Disallow: /api + +User-agent: Googlebot +User-agent: AdsBot-Google +Disallow: /api + +User-agent: * +Disallow: /api
\ No newline at end of file diff --git a/src/public/file.rs b/src/public/file.rs index 88b45b8..b796bc0 100644 --- a/src/public/file.rs +++ b/src/public/file.rs @@ -31,6 +31,10 @@ pub async fn favicon() -> Response { super::serve("/favicon.ico").await } +pub async fn robots() -> Response { + super::serve("/robots.txt").await +} + #[derive(Deserialize)] pub struct AvatarRequest { user_id: u64, diff --git a/src/public/mod.rs b/src/public/mod.rs index 82c994d..76796ea 100644 --- a/src/public/mod.rs +++ b/src/public/mod.rs @@ -35,6 +35,7 @@ pub fn router() -> Router { Router::new() .nest("/", pages::router()) .route("/favicon.ico", get(file::favicon)) + .route("/robots.txt", get(file::robots)) .route("/js/*path", get(file::js)) .route("/css/*path", get(file::css)) .route("/fonts/*path", get(file::fonts)) @@ -71,7 +72,7 @@ pub async fn serve(path: &str) -> Response { res.headers_mut().insert( HeaderName::from_static("cache-control"), - HeaderValue::from_static("public max-age=300"), + HeaderValue::from_static("max-age=300"), ); res.into_response() diff --git a/src/public/pages.rs b/src/public/pages.rs index 32056b7..6d5c0de 100644 --- a/src/public/pages.rs +++ b/src/public/pages.rs @@ -1,13 +1,12 @@ use axum::{ response::{IntoResponse, Redirect, Response}, - routing::get, - Router, + routing::get, Router }; use crate::{ public::console, types::{ - extract::{AuthorizedUser, Log}, + extract::{AuthorizedUser, Log, UserAgent}, http::ResponseCode, }, }; @@ -58,6 +57,15 @@ async fn wordpress(_: Log) -> Response { ResponseCode::ImATeapot.text("Hello i am a teapot owo") } +async fn forgot(UserAgent(agent): UserAgent, _: Log) -> Response { + + if agent.starts_with("curl") { + return super::serve("/404.html").await + } + + Redirect::to("https://www.youtube.com/watch?v=dQw4w9WgXcQ").into_response() +} + pub fn router() -> Router { Router::new() .route("/", get(root)) @@ -69,4 +77,5 @@ pub fn router() -> Router { .route("/wp-admin", get(wordpress)) .route("/admin", get(admin)) .route("/docs", get(api)) + .route("/forgot", get(forgot)) } diff --git a/src/types/extract.rs b/src/types/extract.rs index 8292da7..6a01ad2 100644 --- a/src/types/extract.rs +++ b/src/types/extract.rs @@ -7,7 +7,7 @@ use axum::{ async_trait, body::HttpBody, extract::{ConnectInfo, FromRequest, FromRequestParts}, - http::{request::Parts, Request}, + http::{request::Parts, Request, header::USER_AGENT}, response::Response, BoxError, RequestExt, }; @@ -236,6 +236,30 @@ pub trait Check { } } +pub struct UserAgent(pub String); + +#[async_trait] +impl<S> FromRequestParts<S> for UserAgent +where + S: Send + Sync, +{ + type Rejection = Response; + + async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self> { + let agent = parts.headers.get(USER_AGENT); + + let Some(agent) = agent else { + return Err(ResponseCode::BadRequest.text("Bad Request")); + }; + + let Ok(agent) = agent.to_str() else { + return Err(ResponseCode::BadRequest.text("Bad Request")); + }; + + Ok(UserAgent(agent.to_string())) + } +} + async fn read_body<S, B>(mut req: Request<B>, state: &S) -> Result<Vec<u8>> where B: HttpBody + Sync + Send + 'static, |